/////////////////////////////////////////////////////////////////////////
//
// Amuse Engine SDK - core/math/vector/Fpu
// Copyright (c) 2014.  All Rights Reserved
//
// File:		AEVector4f_Fpu.h
// Author:		Gianluca Belardelli
// Date:		20/01/2014
//
/////////////////////////////////////////////////////////////////////////
#ifndef _AEVECTOR4FFPU_INL_
#define _AEVECTOR4FFPU_INL_

#ifndef AEVECTOR4F_CONSTRUCTORS
AE_FORCEINLINE AEVector4f::AEVector4f( AEFLOAT32 fX, AEFLOAT32 fY, AEFLOAT32 fZ, AEFLOAT32 fW )
{
	m_qfVector.quadFloat[0] = fX;
	m_qfVector.quadFloat[1] = fY;
	m_qfVector.quadFloat[2] = fZ;
	m_qfVector.quadFloat[3] = fW;
}

AE_FORCEINLINE AEVector4f::AEVector4f( const AEQuadFloat32 &qfValue )
{
	m_qfVector.quadFloat[0] = qfValue.quadFloat[0];
	m_qfVector.quadFloat[1] = qfValue.quadFloat[1];
	m_qfVector.quadFloat[2] = qfValue.quadFloat[2];
	m_qfVector.quadFloat[3] = qfValue.quadFloat[3];
}

AE_FORCEINLINE AEVector4f::AEVector4f( const AEVector4f &vcCopy )
{
	m_qfVector.quadFloat[0] = vcCopy.m_qfVector.quadFloat[0];
	m_qfVector.quadFloat[1] = vcCopy.m_qfVector.quadFloat[1];
	m_qfVector.quadFloat[2] = vcCopy.m_qfVector.quadFloat[2];
	m_qfVector.quadFloat[3] = vcCopy.m_qfVector.quadFloat[3];
}
#endif // AEVECTOR4F_CONSTRUCTORS

#ifndef AEVECTOR4F_BASESETS
AE_FORCEINLINE void AEVector4f::Set( AEFLOAT32 fX, AEFLOAT32 fY, AEFLOAT32 fZ, AEFLOAT32 fW )
{
	m_qfVector.quadFloat[0] = fX;
	m_qfVector.quadFloat[1] = fY;
	m_qfVector.quadFloat[2] = fZ;
	m_qfVector.quadFloat[3] = fW;
}

AE_FORCEINLINE void AEVector4f::Set( AESimdFloat32ConstRef fX, AESimdFloat32ConstRef fY, AESimdFloat32ConstRef fZ, AESimdFloat32ConstRef fW )
{
	m_qfVector.quadFloat[0] = fX.GetReal();
	m_qfVector.quadFloat[1] = fY.GetReal();
	m_qfVector.quadFloat[2] = fZ.GetReal();
	m_qfVector.quadFloat[3] = fW.GetReal();
}

AE_FORCEINLINE void AEVector4f::SetAll( const AEFLOAT32 &fValue )
{
	m_qfVector.quadFloat[0] = fValue;
	m_qfVector.quadFloat[1] = fValue;
	m_qfVector.quadFloat[2] = fValue;
	m_qfVector.quadFloat[3] = fValue;
}

AE_FORCEINLINE void AEVector4f::SetAll( AESimdFloat32ConstRef fValue )
{
	SetAll( fValue.GetReal() );
}

AE_FORCEINLINE void AEVector4f::SetZero( void )
{
	m_qfVector.quadFloat[0] = AEFLOAT32( 0 );
	m_qfVector.quadFloat[1] = AEFLOAT32( 0 );
	m_qfVector.quadFloat[2] = AEFLOAT32( 0 );
	m_qfVector.quadFloat[3] = AEFLOAT32( 0 );
}

template <AEINT32 I> 
AE_FORCEINLINE void AEVector4f::ZeroComponent( void )
{
	AE_VECTOR4F_SUBINDEX_CHECK;
	m_qfVector.quadFloat[I] = AEFLOAT32( 0 );
}

AE_FORCEINLINE void AEVector4f::ZeroComponent( const AEINT32 nIndex )
{
	AEASSERT_MSG( ( nIndex >= 0 ) && ( nIndex < 4 ), "Component index out of range");
	m_qfVector.quadFloat[ nIndex ] = AEFLOAT32( 0 );
}

#endif // AEVECTOR4F_BASESETS

#ifndef AEVECTOR4F_ADVSETS

AE_FORCEINLINE void AEVector4f::SetAdd( AEVector4fRefParam vcVector1, AEVector4fRefParam vcVector2 )
{
	m_qfVector.quadFloat[0] = vcVector1.m_qfVector.quadFloat[0] + vcVector2.m_qfVector.quadFloat[0];
	m_qfVector.quadFloat[1] = vcVector1.m_qfVector.quadFloat[1] + vcVector2.m_qfVector.quadFloat[1];
	m_qfVector.quadFloat[2] = vcVector1.m_qfVector.quadFloat[2] + vcVector2.m_qfVector.quadFloat[2];
	m_qfVector.quadFloat[3] = vcVector1.m_qfVector.quadFloat[3] + vcVector2.m_qfVector.quadFloat[3];
}

AE_FORCEINLINE void AEVector4f::SetSub( AEVector4fRefParam vcVector1, AEVector4fRefParam vcVector2 )
{
	m_qfVector.quadFloat[0] = vcVector1.m_qfVector.quadFloat[0] - vcVector2.m_qfVector.quadFloat[0];
	m_qfVector.quadFloat[1] = vcVector1.m_qfVector.quadFloat[1] - vcVector2.m_qfVector.quadFloat[1];
	m_qfVector.quadFloat[2] = vcVector1.m_qfVector.quadFloat[2] - vcVector2.m_qfVector.quadFloat[2];
	m_qfVector.quadFloat[3] = vcVector1.m_qfVector.quadFloat[3] - vcVector2.m_qfVector.quadFloat[3];
}

AE_FORCEINLINE void AEVector4f::SetMul( AEVector4fRefParam vcVector1, AEVector4fRefParam vcVector2 )
{
	m_qfVector.quadFloat[0] = vcVector1.m_qfVector.quadFloat[0] * vcVector2.m_qfVector.quadFloat[0];
	m_qfVector.quadFloat[1] = vcVector1.m_qfVector.quadFloat[1] * vcVector2.m_qfVector.quadFloat[1];
	m_qfVector.quadFloat[2] = vcVector1.m_qfVector.quadFloat[2] * vcVector2.m_qfVector.quadFloat[2];
	m_qfVector.quadFloat[3] = vcVector1.m_qfVector.quadFloat[3] * vcVector2.m_qfVector.quadFloat[3];
}

AE_FORCEINLINE void AEVector4f::SetMul( AEVector4fRefParam vcVector, AESimdFloat32ConstRef fValue )
{
	const AEFLOAT32 fMul = fValue.GetReal();
	m_qfVector.quadFloat[0] = fMul * vcVector.m_qfVector.quadFloat[0];
	m_qfVector.quadFloat[1] = fMul * vcVector.m_qfVector.quadFloat[1];
	m_qfVector.quadFloat[2] = fMul * vcVector.m_qfVector.quadFloat[2];
	m_qfVector.quadFloat[3] = fMul * vcVector.m_qfVector.quadFloat[3];
}

AE_FORCEINLINE void AEVector4f::SetSubMul( AEVector4fRefParam vcVector1, AEVector4fRefParam vcVector2, AESimdFloat32ConstRef fValue )
{
	const AEFLOAT32 fVal = fValue.GetReal();
	m_qfVector.quadFloat[0] = vcVector1.m_qfVector.quadFloat[0] - fVal * vcVector2.m_qfVector.quadFloat[0];
	m_qfVector.quadFloat[1] = vcVector1.m_qfVector.quadFloat[1] - fVal * vcVector2.m_qfVector.quadFloat[1];
	m_qfVector.quadFloat[2] = vcVector1.m_qfVector.quadFloat[2] - fVal * vcVector2.m_qfVector.quadFloat[2];
	m_qfVector.quadFloat[3] = vcVector1.m_qfVector.quadFloat[3] - fVal * vcVector2.m_qfVector.quadFloat[3];
}

AE_FORCEINLINE void AEVector4f::SetAddMul( AEVector4fRefParam vcVector1, AEVector4fRefParam vcVector2, AESimdFloat32ConstRef fValue )
{
	const AEFLOAT32 fVal = fValue.GetReal();
	m_qfVector.quadFloat[0] = vcVector1.m_qfVector.quadFloat[0] + fVal * vcVector2.m_qfVector.quadFloat[0];
	m_qfVector.quadFloat[1] = vcVector1.m_qfVector.quadFloat[1] + fVal * vcVector2.m_qfVector.quadFloat[1];
	m_qfVector.quadFloat[2] = vcVector1.m_qfVector.quadFloat[2] + fVal * vcVector2.m_qfVector.quadFloat[2];
	m_qfVector.quadFloat[3] = vcVector1.m_qfVector.quadFloat[3] + fVal * vcVector2.m_qfVector.quadFloat[3];
}

AE_FORCEINLINE void AEVector4f::SetAddMul( AEVector4fRefParam vcVector1, AEVector4fRefParam vcVector2, AEVector4fRefParam vcVector3 )
{
	m_qfVector.quadFloat[0] = vcVector1.m_qfVector.quadFloat[0] + vcVector2.m_qfVector.quadFloat[0] * vcVector3.m_qfVector.quadFloat[0];
	m_qfVector.quadFloat[1] = vcVector1.m_qfVector.quadFloat[1] + vcVector2.m_qfVector.quadFloat[1] * vcVector3.m_qfVector.quadFloat[1];
	m_qfVector.quadFloat[2] = vcVector1.m_qfVector.quadFloat[2] + vcVector2.m_qfVector.quadFloat[2] * vcVector3.m_qfVector.quadFloat[2];
	m_qfVector.quadFloat[3] = vcVector1.m_qfVector.quadFloat[3] + vcVector2.m_qfVector.quadFloat[3] * vcVector3.m_qfVector.quadFloat[3];
}

AE_FORCEINLINE void AEVector4f::SetSubMul( AEVector4fRefParam vcVector1, AEVector4fRefParam vcVector2, AEVector4fRefParam vcVector3 )
{
	m_qfVector.quadFloat[0] = vcVector1.m_qfVector.quadFloat[0] - vcVector2.m_qfVector.quadFloat[0] * vcVector3.m_qfVector.quadFloat[0];
	m_qfVector.quadFloat[1] = vcVector1.m_qfVector.quadFloat[1] - vcVector2.m_qfVector.quadFloat[1] * vcVector3.m_qfVector.quadFloat[1];
	m_qfVector.quadFloat[2] = vcVector1.m_qfVector.quadFloat[2] - vcVector2.m_qfVector.quadFloat[2] * vcVector3.m_qfVector.quadFloat[2];
	m_qfVector.quadFloat[3] = vcVector1.m_qfVector.quadFloat[3] - vcVector2.m_qfVector.quadFloat[3] * vcVector3.m_qfVector.quadFloat[3];
}

AE_FORCEINLINE void AEVector4f::SetCross( AEVector4fRefParam vcVector1, AEVector4fRefParam vcVector2 )
{
	const AEFLOAT32 fX = vcVector1.m_qfVector.quadFloat[1]*vcVector2.m_qfVector.quadFloat[2] - vcVector1.m_qfVector.quadFloat[2]*vcVector2.m_qfVector.quadFloat[1];
	const AEFLOAT32 fY = vcVector1.m_qfVector.quadFloat[2]*vcVector2.m_qfVector.quadFloat[0] - vcVector1.m_qfVector.quadFloat[0]*vcVector2.m_qfVector.quadFloat[2];
	const AEFLOAT32 fZ = vcVector1.m_qfVector.quadFloat[0]*vcVector2.m_qfVector.quadFloat[1] - vcVector1.m_qfVector.quadFloat[1]*vcVector2.m_qfVector.quadFloat[0];
	Set( fX, fY, fZ , AEFLOAT32( 0 ) );
}

#endif // AEVECTOR4F_ADVSETS

#ifndef AE_VECTOR4F_NEGFUNCS

template <AEINT32 N>
AE_FORCEINLINE void AEVector4f::SetNeg( AEVector4fRefParam vcVector )
{
	AE_VECTOR4F_UNSUPPORTED_LENGTH_CHECK;
	m_qfVector.quadFloat[0] = ( N > 0 ) ? -vcVector.m_qfVector.quadFloat[0] : vcVector.m_qfVector.quadFloat[0];
	m_qfVector.quadFloat[1] = ( N > 1 ) ? -vcVector.m_qfVector.quadFloat[1] : vcVector.m_qfVector.quadFloat[1];
	m_qfVector.quadFloat[2] = ( N > 2 ) ? -vcVector.m_qfVector.quadFloat[2] : vcVector.m_qfVector.quadFloat[2];
	m_qfVector.quadFloat[3] = ( N > 3 ) ? -vcVector.m_qfVector.quadFloat[3] : vcVector.m_qfVector.quadFloat[3];
}

#endif // AE_VECTOR4F_NEGFUNCS

#ifndef AE_VECTOR4F_ABSFUNCS

AE_FORCEINLINE void AEVector4f::SetAbs( AEVector4fRefParam vcVector )
{
	m_qfVector.quadFloat[0] = AEMath::Abs( vcVector.m_qfVector.quadFloat[0] );
	m_qfVector.quadFloat[1] = AEMath::Abs( vcVector.m_qfVector.quadFloat[1] );
	m_qfVector.quadFloat[2] = AEMath::Abs( vcVector.m_qfVector.quadFloat[2] );
	m_qfVector.quadFloat[3] = AEMath::Abs( vcVector.m_qfVector.quadFloat[3] );
}

#endif // AE_VECTOR4F_ABSFUNCS

#ifndef AE_VECTOR4F_MINMAXFUNCS

AE_FORCEINLINE void AEVector4f::SetMin( AEVector4fRefParam vcVector1, AEVector4fRefParam vcVector2 )
{
	m_qfVector.quadFloat[0] = AEMath::Min<AEFLOAT32>( vcVector1.m_qfVector.quadFloat[0], vcVector2.m_qfVector.quadFloat[0] );
	m_qfVector.quadFloat[1] = AEMath::Min<AEFLOAT32>( vcVector1.m_qfVector.quadFloat[1], vcVector2.m_qfVector.quadFloat[1] );
	m_qfVector.quadFloat[2] = AEMath::Min<AEFLOAT32>( vcVector1.m_qfVector.quadFloat[2], vcVector2.m_qfVector.quadFloat[2] );
	m_qfVector.quadFloat[3] = AEMath::Min<AEFLOAT32>( vcVector1.m_qfVector.quadFloat[3], vcVector2.m_qfVector.quadFloat[3] );
}

AE_FORCEINLINE void AEVector4f::SetMax( AEVector4fRefParam vcVector1, AEVector4fRefParam vcVector2 )
{
	m_qfVector.quadFloat[0] = AEMath::Max<AEFLOAT32>( vcVector1.m_qfVector.quadFloat[0], vcVector2.m_qfVector.quadFloat[0] );
	m_qfVector.quadFloat[1] = AEMath::Max<AEFLOAT32>( vcVector1.m_qfVector.quadFloat[1], vcVector2.m_qfVector.quadFloat[1] );
	m_qfVector.quadFloat[2] = AEMath::Max<AEFLOAT32>( vcVector1.m_qfVector.quadFloat[2], vcVector2.m_qfVector.quadFloat[2] );
	m_qfVector.quadFloat[3] = AEMath::Max<AEFLOAT32>( vcVector1.m_qfVector.quadFloat[3], vcVector2.m_qfVector.quadFloat[3] );
}

#endif // AE_VECTOR4F_MINMAXFUNCS

#ifndef AE_VECTOR4F_DOTFUNCS

template <AEINT32 N>
AE_FORCEINLINE const AESimdFloat32 AEVector4f::GetDot( AEVector4fRefParam vcVector ) const
{
	AE_VECTOR4F_UNSUPPORTED_LENGTH_CHECK;
	AEFLOAT32 fSum  = m_qfVector.quadFloat[0] * vcVector.m_qfVector.quadFloat[0];
	
	if( N > 1 )
		fSum += m_qfVector.quadFloat[1] * vcVector.m_qfVector.quadFloat[1];
	
	if( N > 2 )
		fSum += m_qfVector.quadFloat[2] * vcVector.m_qfVector.quadFloat[2];
	
	if( N > 3 )
		fSum += m_qfVector.quadFloat[3] * vcVector.m_qfVector.quadFloat[3];
	
	return AESimdFloat32::Convert( fSum );
}

AE_FORCEINLINE const AESimdFloat32 AEVector4f::Dot4xyz1( AEVector4fRefParam vcVector ) const
{
	return	AESimdFloat32::Convert(	
		( m_qfVector.quadFloat[0] * vcVector.m_qfVector.quadFloat[0] ) + 
		( m_qfVector.quadFloat[1] * vcVector.m_qfVector.quadFloat[1] ) + 
		( m_qfVector.quadFloat[2] * vcVector.m_qfVector.quadFloat[2] ) + 
		 m_qfVector.quadFloat[3] );
}

#endif // AE_VECTOR4F_DOTFUNCS

#ifndef AE_VECTOR4F_HORIZFUNCS

template <AEINT32 N>
AE_FORCEINLINE const AESimdFloat32 AEVector4f::GetHorizontalAdd( void ) const
{
	AE_VECTOR4F_UNSUPPORTED_LENGTH_CHECK;
	AEFLOAT32 fSum  = m_qfVector.quadFloat[0];
	
	if( N > 1 )
		fSum += m_qfVector.quadFloat[1];
	
	if( N > 2 )
		fSum += m_qfVector.quadFloat[2];
	
	if( N > 3 )
		fSum += m_qfVector.quadFloat[3];
	
	return AESimdFloat32::Convert( fSum );
}

template <AEINT32 N>
AE_FORCEINLINE const AESimdFloat32 AEVector4f::GetHorizontalMul( void ) const
{
	AE_VECTOR4F_UNSUPPORTED_LENGTH_CHECK;
	AEFLOAT32 fProd  = m_qfVector.quadFloat[0];
	
	if( N > 1 )
		fProd *= m_qfVector.quadFloat[1];
	
	if( N > 2 )
		fProd *= m_qfVector.quadFloat[2];
	
	if( N > 3 )
		fProd *= m_qfVector.quadFloat[3];
	
	return AESimdFloat32::Convert( fProd );
	
}

template <>
AE_FORCEINLINE const AESimdFloat32 AEVector4f::GetHorizontalMax<1>( void ) const
{
	return GetComponent<0>();
}

template <>
AE_FORCEINLINE const AESimdFloat32 AEVector4f::GetHorizontalMax<2>( void ) const
{
	return AESimdFloat32::Convert( AEMath::Max<AEFLOAT32>( m_qfVector.quadFloat[0], m_qfVector.quadFloat[1] ) );
}

template <>
AE_FORCEINLINE const AESimdFloat32 AEVector4f::GetHorizontalMax<3>( void ) const
{
	const AEFLOAT32 fMax01 = AEMath::Max<AEFLOAT32>( m_qfVector.quadFloat[0], m_qfVector.quadFloat[1] );
	return AESimdFloat32::Convert( AEMath::Max<AEFLOAT32>( fMax01, m_qfVector.quadFloat[2] ) );
}

template <>
AE_FORCEINLINE const AESimdFloat32 AEVector4f::GetHorizontalMax<4>( void ) const
{
	const AEFLOAT32 fMax01 = AEMath::Max<AEFLOAT32>( m_qfVector.quadFloat[0], m_qfVector.quadFloat[1] );
	const AEFLOAT32 fMax23 = AEMath::Max<AEFLOAT32>( m_qfVector.quadFloat[2], m_qfVector.quadFloat[3] );
	return AESimdFloat32::Convert( AEMath::Max<AEFLOAT32>( fMax01, fMax23 ) );
}

template <AEINT32 N>
AE_FORCEINLINE const AESimdFloat32 AEVector4f::GetHorizontalMax( void ) const
{
	AE_VECTOR4F_NOT_IMPLEMENTED;
	return AESimdFloat32::GetConstant<AE_QUADREAL_0>();
}

template <>
AE_FORCEINLINE const AESimdFloat32 AEVector4f::GetHorizontalMin<1>( void ) const
{
	return GetComponent<0>();
}

template <>
AE_FORCEINLINE const AESimdFloat32 AEVector4f::GetHorizontalMin<2>( void ) const
{
	return AESimdFloat32::Convert( AEMath::Min<AEFLOAT32>( m_qfVector.quadFloat[0], m_qfVector.quadFloat[1] ) );
}

template <>
AE_FORCEINLINE const AESimdFloat32 AEVector4f::GetHorizontalMin<3>( void ) const
{
	const AEFLOAT32 fMin01 = AEMath::Min<AEFLOAT32>( m_qfVector.quadFloat[0], m_qfVector.quadFloat[1] );
	return AESimdFloat32::Convert( AEMath::Min<AEFLOAT32>( fMin01, m_qfVector.quadFloat[2] ) );
}

template <>
AE_FORCEINLINE const AESimdFloat32 AEVector4f::GetHorizontalMin<4>( void ) const
{
	const AEFLOAT32 fMin01 = AEMath::Min<AEFLOAT32>( m_qfVector.quadFloat[0], m_qfVector.quadFloat[1] );
	const AEFLOAT32 fMin23 = AEMath::Min<AEFLOAT32>( m_qfVector.quadFloat[2], m_qfVector.quadFloat[3] );
	return AESimdFloat32::Convert( AEMath::Min<AEFLOAT32>( fMin01, fMin23 ) );
}

template <AEINT32 N>
AE_FORCEINLINE const AESimdFloat32 AEVector4f::GetHorizontalMin( void ) const
{
	AE_VECTOR4F_NOT_IMPLEMENTED;
	return AESimdFloat32::GetConstant<AE_QUADREAL_0>();
}

#endif // AE_VECTOR4F_HORIZFUNCS

#ifndef AE_VECTOR4F_SETXYZWFUNCS

AE_FORCEINLINE void AEVector4f::SetXYZ_W( AEVector4fRefParam vcXYZVector, AEVector4fRefParam vcWVector )
{
	m_qfVector.quadFloat[0] = vcXYZVector.m_qfVector.quadFloat[0];
	m_qfVector.quadFloat[1] = vcXYZVector.m_qfVector.quadFloat[1];
	m_qfVector.quadFloat[2] = vcXYZVector.m_qfVector.quadFloat[2];
	m_qfVector.quadFloat[3] = vcWVector.m_qfVector.quadFloat[3];
}

AE_FORCEINLINE void AEVector4f::SetXYZ_W( AEVector4fRefParam vcXYZVector, AESimdFloat32ConstRef fW )
{
	m_qfVector.quadFloat[0] = vcXYZVector.m_qfVector.quadFloat[0];
	m_qfVector.quadFloat[1] = vcXYZVector.m_qfVector.quadFloat[1];
	m_qfVector.quadFloat[2] = vcXYZVector.m_qfVector.quadFloat[2];
	m_qfVector.quadFloat[3] = fW.GetReal();
}

AE_FORCEINLINE void AEVector4f::SetW( AEVector4fRefParam vcWVector )
{
	m_qfVector.quadFloat[3] = vcWVector.m_qfVector.quadFloat[3];
}

AE_FORCEINLINE void AEVector4f::SetXYZ( AEVector4fRefParam vcXYZVector )
{
	m_qfVector.quadFloat[0] = vcXYZVector.m_qfVector.quadFloat[0];
	m_qfVector.quadFloat[1] = vcXYZVector.m_qfVector.quadFloat[1];
	m_qfVector.quadFloat[2] = vcXYZVector.m_qfVector.quadFloat[2];
}

AE_FORCEINLINE void AEVector4f::AddXYZ( AEVector4fRefParam vcXYZVector )
{
	m_qfVector.quadFloat[0] += vcXYZVector.m_qfVector.quadFloat[0];
	m_qfVector.quadFloat[1] += vcXYZVector.m_qfVector.quadFloat[1];
	m_qfVector.quadFloat[2] += vcXYZVector.m_qfVector.quadFloat[2];
	
	#ifdef AEDEBUG
		#ifdef AE_REAL_IS_DOUBLE
			*( (AEUINT64*)&( m_qfVector.quadFloat[3] ) ) = 0xffffffffffffffffull;
		#else
			 *( (AEUINT32*)&( m_qfVector.quadFloat[3] ) ) = 0xffffffff;
		#endif
	#endif
}

AE_FORCEINLINE void AEVector4f::SubXYZ( AEVector4fRefParam vcXYZVector )
{
	m_qfVector.quadFloat[0] -= vcXYZVector.m_qfVector.quadFloat[0];
	m_qfVector.quadFloat[1] -= vcXYZVector.m_qfVector.quadFloat[1];
	m_qfVector.quadFloat[2] -= vcXYZVector.m_qfVector.quadFloat[2];

	#ifdef AEDEBUG
		#ifdef AE_REAL_IS_DOUBLE
			*( (AEUINT64*)&( m_qfVector.quadFloat[3] ) ) = 0xffffffffffffffffull;
		#else
			 *( (AEUINT32*)&( m_qfVector.quadFloat[3] ) ) = 0xffffffff;
		#endif
	#endif
}

AE_FORCEINLINE void AEVector4f::SetXYZ( AEFLOAT32 fValue )
{
	m_qfVector.quadFloat[0] = fValue;
	m_qfVector.quadFloat[1] = fValue;
	m_qfVector.quadFloat[2] = fValue;
}

AE_FORCEINLINE void AEVector4f::SetXYZ( AESimdFloat32ConstRef fValue )
{
	SetXYZ( fValue.GetReal() );
}

AE_FORCEINLINE void AEVector4f::SetXYZ_0( AEVector4fRefParam vcXYZVector )
{
	SetXYZ( vcXYZVector );
	m_qfVector.quadFloat[3] = AEFLOAT32( 0 );
}

#endif // AE_VECTOR4F_SETXYZWFUNCS

#ifndef AE_VECTOR4F_OPERATORS

AE_FORCEINLINE AEFLOAT32 &AEVector4f::operator() ( AEINT32 nIndex )
{
	AEASSERT_MSG( nIndex >= 0 && nIndex < 4, "index out of bounds for component access");
	return m_qfVector.quadFloat[ nIndex ];
}

AE_FORCEINLINE const AEFLOAT32 &AEVector4f::operator() ( AEINT32 nIndex ) const
{
	AEASSERT_MSG( nIndex >= 0 && nIndex < 4, "index out of bounds for component access");
	return const_cast<const AEFLOAT32&>( m_qfVector.quadFloat[ nIndex ] );
}

#endif // AE_VECTOR4F_OPERATORS

#ifndef AE_VECTOR4F_GETCOMPFUNCS

AE_FORCEINLINE const AESimdFloat32 AEVector4f::GetComponent( const AEINT32 nIndex ) const
{
	AEASSERT_MSG( nIndex >= 0 && nIndex < 4, "index out of bounds for component access");
	return AESimdFloat32::Convert( m_qfVector.quadFloat[ nIndex ] );
}

template <AEINT32 I>
AE_FORCEINLINE const AESimdFloat32 AEVector4f::GetComponent( void ) const
{
	AE_VECTOR4F_SUBINDEX_CHECK;
	return AESimdFloat32::Convert( m_qfVector.quadFloat[I] );
}

#endif // AE_VECTOR4F_GETCOMPFUNCS

#ifndef AE_VECTOR4F_SETCOMPFUNCS

AE_FORCEINLINE void AEVector4f::SetComponent( const AEINT32 nIndex, AESimdFloat32ConstRef fValue )
{
	AEASSERT_MSG( nIndex >= 0 && nIndex < 4, "index out of bounds for component access");
	m_qfVector.quadFloat[ nIndex ] = fValue.GetReal();
}

template <AEINT32 I>
AE_FORCEINLINE void AEVector4f::SetComponent( AESimdFloat32ConstRef fValue )
{
	AE_VECTOR4F_SUBINDEX_CHECK;
	m_qfVector.quadFloat[I] = fValue.GetReal();
}

#endif // AE_VECTOR4F_SETCOMPFUNCS

#ifndef AE_VECTOR4F_CHECKFUNCS

template <AEINT32 N> 
AE_FORCEINLINE AEBOOL32 AEVector4f::IsOk( void ) const
{
	AE_VECTOR4F_UNSUPPORTED_LENGTH_CHECK;
	if (        !AEMath::IsFiniteNumber( m_qfVector.quadFloat[0] ) ) return false;
	if ( ( N > 1 ) && ( !AEMath::IsFiniteNumber( m_qfVector.quadFloat[1] ) ) ) return false;
	if ( ( N > 2 ) && ( !AEMath::IsFiniteNumber( m_qfVector.quadFloat[2] ) ) ) return false;
	if ( ( N > 3 ) && ( !AEMath::IsFiniteNumber( m_qfVector.quadFloat[3] ) ) ) return false;
	return true;
}

#endif // AE_VECTOR4F_CHECKFUNCS

#ifndef AE_VECTOR4F_RECIPROCALFUNCS

namespace AEVector4_AdvancedInterface
{
	template <AEMathAccuracyMode A, AEMathDivByZeroMode D>
	struct unrollf_setReciprocal
	{
		AE_FORCEINLINE static void Apply( AEQuadFloat32 &fSelf, AEVector4fRefParam vcVector )
		{
			AE_VECTOR4F_TEMPLATE_CONFIG_NOT_IMPLEMENTED;
		}
	};
	
	template <AEMathAccuracyMode A>
	struct unrollf_setReciprocal<A, AE_DIV_IGNORE>
	{
		AE_FORCEINLINE static void Apply( AEQuadFloat32 &fSelf, AEVector4fRefParam vcVector )
		{
			switch (A)
			{
				case AE_ACC_23_BIT: 
					{
						fSelf.quadFloat[0] = AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[0] ) ) );
						fSelf.quadFloat[1] = AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[1] ) ) );
						fSelf.quadFloat[2] = AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[2] ) ) );
						fSelf.quadFloat[3] = AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[3] ) ) );
					}
					break;
				case AE_ACC_12_BIT: 
					{
						fSelf.quadFloat[0] = AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[0] ) ) );
						fSelf.quadFloat[1] = AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[1] ) ) );
						fSelf.quadFloat[2] = AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[2] ) ) );
						fSelf.quadFloat[3] = AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[3] ) ) );
					}
					break;
				default:         
					{
						fSelf.quadFloat[0] = AEFLOAT32( 1 ) / vcVector.m_qfVector.quadFloat[0];
						fSelf.quadFloat[1] = AEFLOAT32( 1 ) / vcVector.m_qfVector.quadFloat[1];
						fSelf.quadFloat[2] = AEFLOAT32( 1 ) / vcVector.m_qfVector.quadFloat[2];
						fSelf.quadFloat[3] = AEFLOAT32( 1 ) / vcVector.m_qfVector.quadFloat[3];
					}
					break;
			}
		}
	};
	
	template <AEMathAccuracyMode A>
	struct unrollf_setReciprocal<A, AE_DIV_SET_ZERO>
	{
		AE_FORCEINLINE static void Apply( AEQuadFloat32 &fSelf, AEVector4fRefParam vcVector )
		{
			switch (A)
			{
				case AE_ACC_23_BIT: 
					{
						fSelf.quadFloat[0] = ( ( vcVector.m_qfVector.quadFloat[0] == AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[0] ) ) ) );
						fSelf.quadFloat[1] = ( ( vcVector.m_qfVector.quadFloat[1] == AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[1] ) ) ) );
						fSelf.quadFloat[2] = ( ( vcVector.m_qfVector.quadFloat[2] == AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[2] ) ) ) );
						fSelf.quadFloat[3] = ( ( vcVector.m_qfVector.quadFloat[3] == AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[3] ) ) ) );
					}
					break;
				case AE_ACC_12_BIT: 
					{
						fSelf.quadFloat[0] = ( ( vcVector.m_qfVector.quadFloat[0] == AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[0] ) ) ) );
						fSelf.quadFloat[1] = ( ( vcVector.m_qfVector.quadFloat[1] == AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[1] ) ) ) );
						fSelf.quadFloat[2] = ( ( vcVector.m_qfVector.quadFloat[2] == AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[2] ) ) ) );
						fSelf.quadFloat[3] = ( ( vcVector.m_qfVector.quadFloat[3] == AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[3] ) ) ) );
					}
					break;
				default:         
					{
						fSelf.quadFloat[0] = ( ( vcVector.m_qfVector.quadFloat[0] == AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEFLOAT32( 1 ) / vcVector.m_qfVector.quadFloat[0] );
						fSelf.quadFloat[1] = ( ( vcVector.m_qfVector.quadFloat[1] == AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEFLOAT32( 1 ) / vcVector.m_qfVector.quadFloat[1] );
						fSelf.quadFloat[2] = ( ( vcVector.m_qfVector.quadFloat[2] == AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEFLOAT32( 1 ) / vcVector.m_qfVector.quadFloat[2] );
						fSelf.quadFloat[3] = ( ( vcVector.m_qfVector.quadFloat[3] == AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEFLOAT32( 1 ) / vcVector.m_qfVector.quadFloat[3] );
					}
					break;
			}
		}
	};
	
	template <AEMathAccuracyMode A>
	struct unrollf_setReciprocal<A, AE_DIV_SET_HIGH>
	{
		AE_FORCEINLINE static void Apply( AEQuadFloat32 &fSelf, AEVector4fRefParam vcVector )
		{
			AEFLOAT32 high0 = AEMath::SignBitSet( vcVector.m_qfVector.quadFloat[0] ) ? -AE_FLOAT_HIGH : AE_FLOAT_HIGH;
			AEFLOAT32 high1 = AEMath::SignBitSet( vcVector.m_qfVector.quadFloat[1] ) ? -AE_FLOAT_HIGH : AE_FLOAT_HIGH;
			AEFLOAT32 high2 = AEMath::SignBitSet( vcVector.m_qfVector.quadFloat[2] ) ? -AE_FLOAT_HIGH : AE_FLOAT_HIGH;
			AEFLOAT32 high3 = AEMath::SignBitSet( vcVector.m_qfVector.quadFloat[3] ) ? -AE_FLOAT_HIGH : AE_FLOAT_HIGH;
			switch (A)
			{
			case AE_ACC_23_BIT: 
				{
					fSelf.quadFloat[0] = ( ( vcVector.m_qfVector.quadFloat[0] == AEFLOAT32( 0 ) ) ? high0 : AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[0] ) ) ) );
					fSelf.quadFloat[1] = ( ( vcVector.m_qfVector.quadFloat[1] == AEFLOAT32( 0 ) ) ? high1 : AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[1] ) ) ) );
					fSelf.quadFloat[2] = ( ( vcVector.m_qfVector.quadFloat[2] == AEFLOAT32( 0 ) ) ? high2 : AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[2] ) ) ) );
					fSelf.quadFloat[3] = ( ( vcVector.m_qfVector.quadFloat[3] == AEFLOAT32( 0 ) ) ? high3 : AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[3] ) ) ) );
				}
				break;
			case AE_ACC_12_BIT: 
				{
					fSelf.quadFloat[0] = ( ( vcVector.m_qfVector.quadFloat[0] == AEFLOAT32( 0 ) ) ? high0 : AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[0] ) ) ) );
					fSelf.quadFloat[1] = ( ( vcVector.m_qfVector.quadFloat[1] == AEFLOAT32( 0 ) ) ? high1 : AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[1] ) ) ) );
					fSelf.quadFloat[2] = ( ( vcVector.m_qfVector.quadFloat[2] == AEFLOAT32( 0 ) ) ? high2 : AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[2] ) ) ) );
					fSelf.quadFloat[3] = ( ( vcVector.m_qfVector.quadFloat[3] == AEFLOAT32( 0 ) ) ? high3 : AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[3] ) ) ) );
				}
				break;
			default:         
				{
					fSelf.quadFloat[0] = ( ( vcVector.m_qfVector.quadFloat[0] == AEFLOAT32( 0 ) ) ? high0 : AEFLOAT32( 1 ) / vcVector.m_qfVector.quadFloat[0] );
					fSelf.quadFloat[1] = ( ( vcVector.m_qfVector.quadFloat[1] == AEFLOAT32( 0 ) ) ? high1 : AEFLOAT32( 1 ) / vcVector.m_qfVector.quadFloat[1] );
					fSelf.quadFloat[2] = ( ( vcVector.m_qfVector.quadFloat[2] == AEFLOAT32( 0 ) ) ? high2 : AEFLOAT32( 1 ) / vcVector.m_qfVector.quadFloat[2] );
					fSelf.quadFloat[3] = ( ( vcVector.m_qfVector.quadFloat[3] == AEFLOAT32( 0 ) ) ? high3 : AEFLOAT32( 1 ) / vcVector.m_qfVector.quadFloat[3] );
				}
				break;
			}
		}
	};
	
	template <AEMathAccuracyMode A>
	struct unrollf_setReciprocal<A, AE_DIV_SET_MAX>
	{
		AE_FORCEINLINE static void Apply( AEQuadFloat32 &fSelf, AEVector4fRefParam vcVector )
		{
			AEFLOAT32 max0 = AEMath::SignBitSet( vcVector.m_qfVector.quadFloat[0] ) ? -AE_FLOAT_MAX : AE_FLOAT_MAX;
			AEFLOAT32 max1 = AEMath::SignBitSet( vcVector.m_qfVector.quadFloat[1] ) ? -AE_FLOAT_MAX : AE_FLOAT_MAX;
			AEFLOAT32 max2 = AEMath::SignBitSet( vcVector.m_qfVector.quadFloat[2] ) ? -AE_FLOAT_MAX : AE_FLOAT_MAX;
			AEFLOAT32 max3 = AEMath::SignBitSet( vcVector.m_qfVector.quadFloat[3] ) ? -AE_FLOAT_MAX : AE_FLOAT_MAX;
			switch (A)
			{
			case AE_ACC_23_BIT: 
				{
					fSelf.quadFloat[0] = ( ( vcVector.m_qfVector.quadFloat[0] == AEFLOAT32( 0 ) ) ? max0 : AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[0] ) ) ) );
					fSelf.quadFloat[1] = ( ( vcVector.m_qfVector.quadFloat[1] == AEFLOAT32( 0 ) ) ? max1 : AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[1] ) ) ) );
					fSelf.quadFloat[2] = ( ( vcVector.m_qfVector.quadFloat[2] == AEFLOAT32( 0 ) ) ? max2 : AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[2] ) ) ) );
					fSelf.quadFloat[3] = ( ( vcVector.m_qfVector.quadFloat[3] == AEFLOAT32( 0 ) ) ? max3 : AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[3] ) ) ) );
				}
				break;
			case AE_ACC_12_BIT: 
				{
					fSelf.quadFloat[0] = ( ( vcVector.m_qfVector.quadFloat[0] == AEFLOAT32( 0 ) ) ? max0 : AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[0] ) ) ) );
					fSelf.quadFloat[1] = ( ( vcVector.m_qfVector.quadFloat[1] == AEFLOAT32( 0 ) ) ? max1 : AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[1] ) ) ) );
					fSelf.quadFloat[2] = ( ( vcVector.m_qfVector.quadFloat[2] == AEFLOAT32( 0 ) ) ? max2 : AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[2] ) ) ) );
					fSelf.quadFloat[3] = ( ( vcVector.m_qfVector.quadFloat[3] == AEFLOAT32( 0 ) ) ? max3 : AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[3] ) ) ) );
				}
				break;
			default:         
				{
					fSelf.quadFloat[0] = ( ( vcVector.m_qfVector.quadFloat[0] == AEFLOAT32( 0 ) ) ? max0 : AEFLOAT32( 1 ) / vcVector.m_qfVector.quadFloat[0] );
					fSelf.quadFloat[1] = ( ( vcVector.m_qfVector.quadFloat[1] == AEFLOAT32( 0 ) ) ? max1 : AEFLOAT32( 1 ) / vcVector.m_qfVector.quadFloat[1] );
					fSelf.quadFloat[2] = ( ( vcVector.m_qfVector.quadFloat[2] == AEFLOAT32( 0 ) ) ? max2 : AEFLOAT32( 1 ) / vcVector.m_qfVector.quadFloat[2] );
					fSelf.quadFloat[3] = ( ( vcVector.m_qfVector.quadFloat[3] == AEFLOAT32( 0 ) ) ? max3 : AEFLOAT32( 1 ) / vcVector.m_qfVector.quadFloat[3] );
				}
				break;
			}
		}
	};
	
	template <AEMathAccuracyMode A>
	struct unrollf_setReciprocal<A, AE_DIV_SET_ZERO_AND_ONE>
	{
		AE_FORCEINLINE static void Apply( AEQuadFloat32 &fSelf, AEVector4fRefParam vcVector )
		{
			AEQuadFloat32 val;
			unrollf_setReciprocal<A, AE_DIV_SET_ZERO>::Apply( val ,vcVector );
		
			AEQuadFloat32 absValLessOne;
			absValLessOne.quadFloat[0] = AEMath::Abs( val.quadFloat[0] - AEFLOAT32( 1 ) );
			absValLessOne.quadFloat[1] = AEMath::Abs( val.quadFloat[1] - AEFLOAT32( 1 ) );
			absValLessOne.quadFloat[2] = AEMath::Abs( val.quadFloat[2] - AEFLOAT32( 1 ) );
			absValLessOne.quadFloat[3] = AEMath::Abs( val.quadFloat[3] - AEFLOAT32( 1 ) );
		
			fSelf.quadFloat[0] = ( ( absValLessOne.quadFloat[0] <= AEMATH_EPSILON) ? AEFLOAT32( 1 ) : val.quadFloat[0] );
			fSelf.quadFloat[1] = ( ( absValLessOne.quadFloat[1] <= AEMATH_EPSILON) ? AEFLOAT32( 1 ) : val.quadFloat[1] );
			fSelf.quadFloat[2] = ( ( absValLessOne.quadFloat[2] <= AEMATH_EPSILON) ? AEFLOAT32( 1 ) : val.quadFloat[2] );
			fSelf.quadFloat[3] = ( ( absValLessOne.quadFloat[3] <= AEMATH_EPSILON) ? AEFLOAT32( 1 ) : val.quadFloat[3] );
		}
	};
} // End namespace 

template <AEMathAccuracyMode A, AEMathDivByZeroMode D>
AE_FORCEINLINE void AEVector4f::SetReciprocal( AEVector4fRefParam vcVector )
{
	AEVector4_AdvancedInterface::unrollf_setReciprocal<A,D>::Apply( m_qfVector, vcVector );
}

AE_FORCEINLINE void AEVector4f::SetReciprocal( AEVector4fRefParam vcVector )
{
	AEVector4_AdvancedInterface::unrollf_setReciprocal<AE_ACC_23_BIT,AE_DIV_IGNORE>::Apply( m_qfVector, vcVector );
}

#endif // AE_VECTOR4F_RECIPROCALFUNCS

#ifndef AE_VECTOR4F_DIVFUNCS

namespace AEVector4_AdvancedInterface
{
	template <AEMathAccuracyMode A, AEMathDivByZeroMode D>
	struct unrollf_setDiv
	{
		AE_FORCEINLINE static void Apply( AEQuadFloat32 &qfSelf, AEVector4fRefParam vcVector1, AEVector4fRefParam vcVector2 )
		{
			AE_VECTOR4F_TEMPLATE_CONFIG_NOT_IMPLEMENTED;
		}
	};
	
	template <AEMathAccuracyMode A>
	struct unrollf_setDiv<A, AE_DIV_IGNORE>
	{
		AE_FORCEINLINE static void Apply( AEQuadFloat32 &qfSelf, AEVector4fRefParam vcVector1, AEVector4fRefParam vcVector2 )
		{
			switch (A)
			{
			case AE_ACC_23_BIT: 
				{
					qfSelf.quadFloat[0] = vcVector1.m_qfVector.quadFloat[0] * AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[0] ) ) );
					qfSelf.quadFloat[1] = vcVector1.m_qfVector.quadFloat[1] * AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[1] ) ) );
					qfSelf.quadFloat[2] = vcVector1.m_qfVector.quadFloat[2] * AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[2] ) ) );
					qfSelf.quadFloat[3] = vcVector1.m_qfVector.quadFloat[3] * AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[3] ) ) );
				}
				break;
			case AE_ACC_12_BIT: 
				{
					qfSelf.quadFloat[0] = vcVector1.m_qfVector.quadFloat[0] * AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[0] ) ) );
					qfSelf.quadFloat[1] = vcVector1.m_qfVector.quadFloat[1] * AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[1] ) ) );
					qfSelf.quadFloat[2] = vcVector1.m_qfVector.quadFloat[2] * AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[2] ) ) );
					qfSelf.quadFloat[3] = vcVector1.m_qfVector.quadFloat[3] * AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[3] ) ) );
				}
				break;
			default:         
				{
					qfSelf.quadFloat[0] = vcVector1.m_qfVector.quadFloat[0] / vcVector2.m_qfVector.quadFloat[0];
					qfSelf.quadFloat[1] = vcVector1.m_qfVector.quadFloat[1] / vcVector2.m_qfVector.quadFloat[1];
					qfSelf.quadFloat[2] = vcVector1.m_qfVector.quadFloat[2] / vcVector2.m_qfVector.quadFloat[2];
					qfSelf.quadFloat[3] = vcVector1.m_qfVector.quadFloat[3] / vcVector2.m_qfVector.quadFloat[3];
				}
				break;
			}
		}
	};
	
	template <AEMathAccuracyMode A>
	struct unrollf_setDiv<A, AE_DIV_SET_ZERO>
	{
		AE_FORCEINLINE static void Apply( AEQuadFloat32 &qfSelf, AEVector4fRefParam vcVector1, AEVector4fRefParam vcVector2 )
		{
			switch (A)
			{
			case AE_ACC_23_BIT: 
				{
					qfSelf.quadFloat[0] = ( ( vcVector2.m_qfVector.quadFloat[0] == AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : ( vcVector1.m_qfVector.quadFloat[0] * AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[0] ) ) ) ) );
					qfSelf.quadFloat[1] = ( ( vcVector2.m_qfVector.quadFloat[1] == AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : ( vcVector1.m_qfVector.quadFloat[1] * AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[1] ) ) ) ) );
					qfSelf.quadFloat[2] = ( ( vcVector2.m_qfVector.quadFloat[2] == AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : ( vcVector1.m_qfVector.quadFloat[2] * AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[2] ) ) ) ) );
					qfSelf.quadFloat[3] = ( ( vcVector2.m_qfVector.quadFloat[3] == AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : ( vcVector1.m_qfVector.quadFloat[3] * AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[3] ) ) ) ) );
				}
				break;
			case AE_ACC_12_BIT: 
				{
					qfSelf.quadFloat[0] = ( ( vcVector2.m_qfVector.quadFloat[0] == AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : ( vcVector1.m_qfVector.quadFloat[0] * AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[0] ) ) ) ) );
					qfSelf.quadFloat[1] = ( ( vcVector2.m_qfVector.quadFloat[1] == AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : ( vcVector1.m_qfVector.quadFloat[1] * AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[1] ) ) ) ) );
					qfSelf.quadFloat[2] = ( ( vcVector2.m_qfVector.quadFloat[2] == AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : ( vcVector1.m_qfVector.quadFloat[2] * AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[2] ) ) ) ) );
					qfSelf.quadFloat[3] = ( ( vcVector2.m_qfVector.quadFloat[3] == AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : ( vcVector1.m_qfVector.quadFloat[3] * AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[3] ) ) ) ) );
				}
				break;
			default:         
				{
					qfSelf.quadFloat[0] = ( ( vcVector2.m_qfVector.quadFloat[0] == AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : ( vcVector1.m_qfVector.quadFloat[0] / vcVector2.m_qfVector.quadFloat[0] ) );
					qfSelf.quadFloat[1] = ( ( vcVector2.m_qfVector.quadFloat[1] == AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : ( vcVector1.m_qfVector.quadFloat[1] / vcVector2.m_qfVector.quadFloat[1] ) );
					qfSelf.quadFloat[2] = ( ( vcVector2.m_qfVector.quadFloat[2] == AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : ( vcVector1.m_qfVector.quadFloat[2] / vcVector2.m_qfVector.quadFloat[2] ) );
					qfSelf.quadFloat[3] = ( ( vcVector2.m_qfVector.quadFloat[3] == AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : ( vcVector1.m_qfVector.quadFloat[3] / vcVector2.m_qfVector.quadFloat[3] ) );
				}
				break;
			}
		}
	};
	
	template <AEMathAccuracyMode A>
	struct unrollf_setDiv<A, AE_DIV_SET_HIGH>
	{
		AE_FORCEINLINE static void Apply( AEQuadFloat32 &qfSelf, AEVector4fRefParam vcVector1, AEVector4fRefParam vcVector2 )
		{
			switch (A)
			{
			case AE_ACC_23_BIT: 
				{
					qfSelf.quadFloat[0] = ( ( vcVector2.m_qfVector.quadFloat[0] == AEFLOAT32( 0 ) ) ? ( ( vcVector1.m_qfVector.quadFloat[0] < AEFLOAT32( 0 ) ) ? -AE_FLOAT_HIGH : AE_FLOAT_HIGH) : ( vcVector1.m_qfVector.quadFloat[0] * AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[0] ) ) ) ) );
					qfSelf.quadFloat[1] = ( ( vcVector2.m_qfVector.quadFloat[1] == AEFLOAT32( 0 ) ) ? ( ( vcVector1.m_qfVector.quadFloat[1] < AEFLOAT32( 0 ) ) ? -AE_FLOAT_HIGH : AE_FLOAT_HIGH) : ( vcVector1.m_qfVector.quadFloat[1] * AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[1] ) ) ) ) );
					qfSelf.quadFloat[2] = ( ( vcVector2.m_qfVector.quadFloat[2] == AEFLOAT32( 0 ) ) ? ( ( vcVector1.m_qfVector.quadFloat[2] < AEFLOAT32( 0 ) ) ? -AE_FLOAT_HIGH : AE_FLOAT_HIGH) : ( vcVector1.m_qfVector.quadFloat[2] * AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[2] ) ) ) ) );
					qfSelf.quadFloat[3] = ( ( vcVector2.m_qfVector.quadFloat[3] == AEFLOAT32( 0 ) ) ? ( ( vcVector1.m_qfVector.quadFloat[3] < AEFLOAT32( 0 ) ) ? -AE_FLOAT_HIGH : AE_FLOAT_HIGH) : ( vcVector1.m_qfVector.quadFloat[3] * AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[3] ) ) ) ) );
				}
				break;
			case AE_ACC_12_BIT: 
				{
					qfSelf.quadFloat[0] = ( ( vcVector2.m_qfVector.quadFloat[0] == AEFLOAT32( 0 ) ) ? ( ( vcVector1.m_qfVector.quadFloat[0] < AEFLOAT32( 0 ) ) ? -AE_FLOAT_HIGH : AE_FLOAT_HIGH) : ( vcVector1.m_qfVector.quadFloat[0] * AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[0] ) ) ) ) );
					qfSelf.quadFloat[1] = ( ( vcVector2.m_qfVector.quadFloat[1] == AEFLOAT32( 0 ) ) ? ( ( vcVector1.m_qfVector.quadFloat[1] < AEFLOAT32( 0 ) ) ? -AE_FLOAT_HIGH : AE_FLOAT_HIGH) : ( vcVector1.m_qfVector.quadFloat[1] * AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[1] ) ) ) ) );
					qfSelf.quadFloat[2] = ( ( vcVector2.m_qfVector.quadFloat[2] == AEFLOAT32( 0 ) ) ? ( ( vcVector1.m_qfVector.quadFloat[2] < AEFLOAT32( 0 ) ) ? -AE_FLOAT_HIGH : AE_FLOAT_HIGH) : ( vcVector1.m_qfVector.quadFloat[2] * AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[2] ) ) ) ) );
					qfSelf.quadFloat[3] = ( ( vcVector2.m_qfVector.quadFloat[3] == AEFLOAT32( 0 ) ) ? ( ( vcVector1.m_qfVector.quadFloat[3] < AEFLOAT32( 0 ) ) ? -AE_FLOAT_HIGH : AE_FLOAT_HIGH) : ( vcVector1.m_qfVector.quadFloat[3] * AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[3] ) ) ) ) );
				}
				break;
			default:         
				{
					qfSelf.quadFloat[0] = ( ( vcVector2.m_qfVector.quadFloat[0] == AEFLOAT32( 0 ) ) ? ( ( vcVector1.m_qfVector.quadFloat[0] < AEFLOAT32( 0 ) ) ? -AE_FLOAT_HIGH : AE_FLOAT_HIGH) : ( vcVector1.m_qfVector.quadFloat[0] / vcVector2.m_qfVector.quadFloat[0] ) );
					qfSelf.quadFloat[1] = ( ( vcVector2.m_qfVector.quadFloat[1] == AEFLOAT32( 0 ) ) ? ( ( vcVector1.m_qfVector.quadFloat[1] < AEFLOAT32( 0 ) ) ? -AE_FLOAT_HIGH : AE_FLOAT_HIGH) : ( vcVector1.m_qfVector.quadFloat[1] / vcVector2.m_qfVector.quadFloat[1] ) );
					qfSelf.quadFloat[2] = ( ( vcVector2.m_qfVector.quadFloat[2] == AEFLOAT32( 0 ) ) ? ( ( vcVector1.m_qfVector.quadFloat[2] < AEFLOAT32( 0 ) ) ? -AE_FLOAT_HIGH : AE_FLOAT_HIGH) : ( vcVector1.m_qfVector.quadFloat[2] / vcVector2.m_qfVector.quadFloat[2] ) );
					qfSelf.quadFloat[3] = ( ( vcVector2.m_qfVector.quadFloat[3] == AEFLOAT32( 0 ) ) ? ( ( vcVector1.m_qfVector.quadFloat[3] < AEFLOAT32( 0 ) ) ? -AE_FLOAT_HIGH : AE_FLOAT_HIGH) : ( vcVector1.m_qfVector.quadFloat[3] / vcVector2.m_qfVector.quadFloat[3] ) );
				}
				break;
			}
		}
	};
	
	template <AEMathAccuracyMode A>
	struct unrollf_setDiv<A, AE_DIV_SET_MAX>
	{
		AE_FORCEINLINE static void Apply( AEQuadFloat32 &qfSelf, AEVector4fRefParam vcVector1, AEVector4fRefParam vcVector2 )
		{
			switch (A)
			{
			case AE_ACC_23_BIT: 
				{
					qfSelf.quadFloat[0] = ( ( vcVector2.m_qfVector.quadFloat[0] == AEFLOAT32( 0 ) ) ? ( ( vcVector1.m_qfVector.quadFloat[0] < AEFLOAT32( 0 ) ) ? -AE_FLOAT_MAX : AE_FLOAT_MAX) : ( vcVector1.m_qfVector.quadFloat[0] * AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[0] ) ) ) ) );
					qfSelf.quadFloat[1] = ( ( vcVector2.m_qfVector.quadFloat[1] == AEFLOAT32( 0 ) ) ? ( ( vcVector1.m_qfVector.quadFloat[1] < AEFLOAT32( 0 ) ) ? -AE_FLOAT_MAX : AE_FLOAT_MAX) : ( vcVector1.m_qfVector.quadFloat[1] * AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[1] ) ) ) ) );
					qfSelf.quadFloat[2] = ( ( vcVector2.m_qfVector.quadFloat[2] == AEFLOAT32( 0 ) ) ? ( ( vcVector1.m_qfVector.quadFloat[2] < AEFLOAT32( 0 ) ) ? -AE_FLOAT_MAX : AE_FLOAT_MAX) : ( vcVector1.m_qfVector.quadFloat[2] * AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[2] ) ) ) ) );
					qfSelf.quadFloat[3] = ( ( vcVector2.m_qfVector.quadFloat[3] == AEFLOAT32( 0 ) ) ? ( ( vcVector1.m_qfVector.quadFloat[3] < AEFLOAT32( 0 ) ) ? -AE_FLOAT_MAX : AE_FLOAT_MAX) : ( vcVector1.m_qfVector.quadFloat[3] * AEFLOAT32( AEMath::RcpF32Approx23Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[3] ) ) ) ) );
				}
				break;
			case AE_ACC_12_BIT: 
				{
					qfSelf.quadFloat[0] = ( ( vcVector2.m_qfVector.quadFloat[0] == AEFLOAT32( 0 ) ) ? ( ( vcVector1.m_qfVector.quadFloat[0] < AEFLOAT32( 0 ) ) ? -AE_FLOAT_MAX : AE_FLOAT_MAX) : ( vcVector1.m_qfVector.quadFloat[0] * AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[0] ) ) ) ) );
					qfSelf.quadFloat[1] = ( ( vcVector2.m_qfVector.quadFloat[1] == AEFLOAT32( 0 ) ) ? ( ( vcVector1.m_qfVector.quadFloat[1] < AEFLOAT32( 0 ) ) ? -AE_FLOAT_MAX : AE_FLOAT_MAX) : ( vcVector1.m_qfVector.quadFloat[1] * AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[1] ) ) ) ) );
					qfSelf.quadFloat[2] = ( ( vcVector2.m_qfVector.quadFloat[2] == AEFLOAT32( 0 ) ) ? ( ( vcVector1.m_qfVector.quadFloat[2] < AEFLOAT32( 0 ) ) ? -AE_FLOAT_MAX : AE_FLOAT_MAX) : ( vcVector1.m_qfVector.quadFloat[2] * AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[2] ) ) ) ) );
					qfSelf.quadFloat[3] = ( ( vcVector2.m_qfVector.quadFloat[3] == AEFLOAT32( 0 ) ) ? ( ( vcVector1.m_qfVector.quadFloat[3] < AEFLOAT32( 0 ) ) ? -AE_FLOAT_MAX : AE_FLOAT_MAX) : ( vcVector1.m_qfVector.quadFloat[3] * AEFLOAT32( AEMath::RcpF32Approx12Bit( AEFLOAT32( vcVector2.m_qfVector.quadFloat[3] ) ) ) ) );
				}
				break;
			default:         
				{
					qfSelf.quadFloat[0] = ( ( vcVector2.m_qfVector.quadFloat[0] == AEFLOAT32( 0 ) ) ? ( ( vcVector1.m_qfVector.quadFloat[0] < AEFLOAT32( 0 ) ) ? -AE_FLOAT_MAX : AE_FLOAT_MAX) : ( vcVector1.m_qfVector.quadFloat[0] / vcVector2.m_qfVector.quadFloat[0] ) );
					qfSelf.quadFloat[1] = ( ( vcVector2.m_qfVector.quadFloat[1] == AEFLOAT32( 0 ) ) ? ( ( vcVector1.m_qfVector.quadFloat[1] < AEFLOAT32( 0 ) ) ? -AE_FLOAT_MAX : AE_FLOAT_MAX) : ( vcVector1.m_qfVector.quadFloat[1] / vcVector2.m_qfVector.quadFloat[1] ) );
					qfSelf.quadFloat[2] = ( ( vcVector2.m_qfVector.quadFloat[2] == AEFLOAT32( 0 ) ) ? ( ( vcVector1.m_qfVector.quadFloat[2] < AEFLOAT32( 0 ) ) ? -AE_FLOAT_MAX : AE_FLOAT_MAX) : ( vcVector1.m_qfVector.quadFloat[2] / vcVector2.m_qfVector.quadFloat[2] ) );
					qfSelf.quadFloat[3] = ( ( vcVector2.m_qfVector.quadFloat[3] == AEFLOAT32( 0 ) ) ? ( ( vcVector1.m_qfVector.quadFloat[3] < AEFLOAT32( 0 ) ) ? -AE_FLOAT_MAX : AE_FLOAT_MAX) : ( vcVector1.m_qfVector.quadFloat[3] / vcVector2.m_qfVector.quadFloat[3] ) );
				}
				break;
			}
		}
	};
	
	template <AEMathAccuracyMode A>
	struct unrollf_setDiv<A, AE_DIV_SET_ZERO_AND_ONE>
	{
		AE_FORCEINLINE static void Apply( AEQuadFloat32 &qfSelf, AEVector4fRefParam vcVector1, AEVector4fRefParam vcVector2 )
		{
			AEQuadFloat32 val;
			unrollf_setDiv<A, AE_DIV_SET_ZERO>::apply( val, vcVector1, vcVector2 );
		
			AEQuadFloat32 absValLessOne;
			absValLessOne.quadFloat[0] = AEMath::Abs(val.quadFloat[0] ) - AEFLOAT32( 1 );
			absValLessOne.quadFloat[1] = AEMath::Abs(val.quadFloat[1] ) - AEFLOAT32( 1 );
			absValLessOne.quadFloat[2] = AEMath::Abs(val.quadFloat[2] ) - AEFLOAT32( 1 );
			absValLessOne.quadFloat[3] = AEMath::Abs(val.quadFloat[3] ) - AEFLOAT32( 1 );
		
			qfSelf.quadFloat[0] = ( ( absValLessOne.quadFloat[0] <= AEMATH_EPSILON ) ? AEFLOAT32( 1 ) : val.quadFloat[0] );
			qfSelf.quadFloat[1] = ( ( absValLessOne.quadFloat[1] <= AEMATH_EPSILON ) ? AEFLOAT32( 1 ) : val.quadFloat[1] );
			qfSelf.quadFloat[2] = ( ( absValLessOne.quadFloat[2] <= AEMATH_EPSILON ) ? AEFLOAT32( 1 ) : val.quadFloat[2] );
			qfSelf.quadFloat[3] = ( ( absValLessOne.quadFloat[3] <= AEMATH_EPSILON ) ? AEFLOAT32( 1 ) : val.quadFloat[3] );
		}
	};
} // namespace 

template <AEMathAccuracyMode A, AEMathDivByZeroMode D>
AE_FORCEINLINE void AEVector4f::SetDiv( AEVector4fRefParam vcVector1, AEVector4fRefParam vcVector2 )
{
	AEVector4_AdvancedInterface::unrollf_setDiv<A,D>::Apply( m_qfVector, vcVector1, vcVector2 );
}

AE_FORCEINLINE void AEVector4f::SetDiv( AEVector4fRefParam vcVector1, AEVector4fRefParam vcVector2 )
{
	AEVector4_AdvancedInterface::unrollf_setDiv<AE_ACC_23_BIT,AE_DIV_IGNORE>::Apply( m_qfVector, vcVector1, vcVector2 );
}

template <AEMathAccuracyMode A, AEMathDivByZeroMode D>
AE_FORCEINLINE void AEVector4f::Div( AEVector4fRefParam vcVector )
{
	SetDiv<A,D>( *this, vcVector );
}

AE_FORCEINLINE void AEVector4f::Div( AEVector4fRefParam vcVector )
{
	SetDiv( *this, vcVector );
}

#endif // AE_VECTOR4F_DIVFUNCS

#ifndef AE_VECTOR4F_SQRTFUNCS

namespace AEVector4_AdvancedInterface
{
	template <AEMathAccuracyMode A, AEMathNegSqrtMode S>
	struct unrollf_setSqrt
	{
		AE_FORCEINLINE static void Apply( AEQuadFloat32 &fSelf, AEVector4fRefParam vcVector )
		{
			AE_VECTOR4F_TEMPLATE_CONFIG_NOT_IMPLEMENTED;
		}
	};
	
	template <AEMathAccuracyMode A>
	struct unrollf_setSqrt<A, AE_SQRT_IGNORE>
	{
		AE_FORCEINLINE static void Apply( AEQuadFloat32 &fSelf, AEVector4fRefParam vcVector )
		{
			switch (A)
			{
				case AE_ACC_23_BIT: 
					{
						fSelf.quadFloat[0] = AEFLOAT32( AEMath::RcpF32Approx23Bit( AEMath::InvSqrtF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[0] ) ) ) );
						fSelf.quadFloat[1] = AEFLOAT32( AEMath::RcpF32Approx23Bit( AEMath::InvSqrtF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[1] ) ) ) );
						fSelf.quadFloat[2] = AEFLOAT32( AEMath::RcpF32Approx23Bit( AEMath::InvSqrtF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[2] ) ) ) );
						fSelf.quadFloat[3] = AEFLOAT32( AEMath::RcpF32Approx23Bit( AEMath::InvSqrtF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[3] ) ) ) );
					}
					break;
				case AE_ACC_12_BIT: 
					{
						fSelf.quadFloat[0] = AEFLOAT32( AEMath::RcpF32Approx12Bit( AEMath::InvSqrtF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[0] ) ) ) );
						fSelf.quadFloat[1] = AEFLOAT32( AEMath::RcpF32Approx12Bit( AEMath::InvSqrtF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[1] ) ) ) );
						fSelf.quadFloat[2] = AEFLOAT32( AEMath::RcpF32Approx12Bit( AEMath::InvSqrtF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[2] ) ) ) );
						fSelf.quadFloat[3] = AEFLOAT32( AEMath::RcpF32Approx12Bit( AEMath::InvSqrtF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[3] ) ) ) );
					}
					break;
				default:         
					{
						fSelf.quadFloat[0] = AEMath::Sqrt( vcVector.m_qfVector.quadFloat[0] );
						fSelf.quadFloat[1] = AEMath::Sqrt( vcVector.m_qfVector.quadFloat[1] );
						fSelf.quadFloat[2] = AEMath::Sqrt( vcVector.m_qfVector.quadFloat[2] );
						fSelf.quadFloat[3] = AEMath::Sqrt( vcVector.m_qfVector.quadFloat[3] );
					}
					break;
			}
		}
	};
	
	template <AEMathAccuracyMode A>
	struct unrollf_setSqrt<A, AE_SQRT_SET_ZERO>
	{
		AE_FORCEINLINE static void Apply( AEQuadFloat32 &fSelf, AEVector4fRefParam vcVector )
		{
			switch (A)
			{
			case AE_ACC_23_BIT: 
				{
					fSelf.quadFloat[0] = ( ( vcVector.m_qfVector.quadFloat[0] <= AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEFLOAT32( AEMath::RcpF32Approx23Bit( AEMath::InvSqrtF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[0] ) ) ) ) );
					fSelf.quadFloat[1] = ( ( vcVector.m_qfVector.quadFloat[1] <= AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEFLOAT32( AEMath::RcpF32Approx23Bit( AEMath::InvSqrtF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[1] ) ) ) ) );
					fSelf.quadFloat[2] = ( ( vcVector.m_qfVector.quadFloat[2] <= AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEFLOAT32( AEMath::RcpF32Approx23Bit( AEMath::InvSqrtF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[2] ) ) ) ) );
					fSelf.quadFloat[3] = ( ( vcVector.m_qfVector.quadFloat[3] <= AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEFLOAT32( AEMath::RcpF32Approx23Bit( AEMath::InvSqrtF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[3] ) ) ) ) );
				}
				break;
			case AE_ACC_12_BIT: 
				{
					fSelf.quadFloat[0] = ( ( vcVector.m_qfVector.quadFloat[0] <= AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEFLOAT32( AEMath::RcpF32Approx12Bit( AEMath::InvSqrtF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[0] ) ) ) ) );
					fSelf.quadFloat[1] = ( ( vcVector.m_qfVector.quadFloat[1] <= AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEFLOAT32( AEMath::RcpF32Approx12Bit( AEMath::InvSqrtF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[1] ) ) ) ) );
					fSelf.quadFloat[2] = ( ( vcVector.m_qfVector.quadFloat[2] <= AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEFLOAT32( AEMath::RcpF32Approx12Bit( AEMath::InvSqrtF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[2] ) ) ) ) );
					fSelf.quadFloat[3] = ( ( vcVector.m_qfVector.quadFloat[3] <= AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEFLOAT32( AEMath::RcpF32Approx12Bit( AEMath::InvSqrtF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[3] ) ) ) ) );
				}
				break;
			default:         
				{
					fSelf.quadFloat[0] = ( ( vcVector.m_qfVector.quadFloat[0] <= AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEMath::Sqrt( vcVector.m_qfVector.quadFloat[0] ) );
					fSelf.quadFloat[1] = ( ( vcVector.m_qfVector.quadFloat[1] <= AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEMath::Sqrt( vcVector.m_qfVector.quadFloat[1] ) );
					fSelf.quadFloat[2] = ( ( vcVector.m_qfVector.quadFloat[2] <= AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEMath::Sqrt( vcVector.m_qfVector.quadFloat[2] ) );
					fSelf.quadFloat[3] = ( ( vcVector.m_qfVector.quadFloat[3] <= AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEMath::Sqrt( vcVector.m_qfVector.quadFloat[3] ) );
				}
				break;
			}
		}
	};
} // End namespace 

template <AEMathAccuracyMode A, AEMathNegSqrtMode S>
AE_FORCEINLINE void AEVector4f::SetSqrt( AEVector4fRefParam vcVector )
{
	AEVector4_AdvancedInterface::unrollf_setSqrt<A,S>::Apply( m_qfVector, vcVector );
}

AE_FORCEINLINE void AEVector4f::SetSqrt( AEVector4fRefParam vcVector )
{
	AEVector4_AdvancedInterface::unrollf_setSqrt<AE_ACC_23_BIT, AE_SQRT_SET_ZERO>::Apply( m_qfVector, vcVector );
}


namespace AEVector4_AdvancedInterface
{
	template <AEMathAccuracyMode A, AEMathNegSqrtMode S>
	struct unrollf_setSqrtInverse
	{
		AE_FORCEINLINE static void Apply( AEQuadFloat32 &fSelf, AEVector4fRefParam vcVector )
		{
			AE_VECTOR4F_TEMPLATE_CONFIG_NOT_IMPLEMENTED;
		}
	};
	
	template <AEMathAccuracyMode A>
	struct unrollf_setSqrtInverse<A, AE_SQRT_IGNORE>
	{
		AE_FORCEINLINE static void Apply( AEQuadFloat32 &fSelf, AEVector4fRefParam vcVector )
		{
			switch (A)
			{
			case AE_ACC_23_BIT: 
				{
					fSelf.quadFloat[0] = AEFLOAT32( AEMath::InvSqrtF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[0] ) ) );
					fSelf.quadFloat[1] = AEFLOAT32( AEMath::InvSqrtF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[1] ) ) );
					fSelf.quadFloat[2] = AEFLOAT32( AEMath::InvSqrtF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[2] ) ) );
					fSelf.quadFloat[3] = AEFLOAT32( AEMath::InvSqrtF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[3] ) ) );
				}
				break;
			case AE_ACC_12_BIT: 
				{
					fSelf.quadFloat[0] = AEFLOAT32( AEMath::InvSqrtF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[0] ) ) );
					fSelf.quadFloat[1] = AEFLOAT32( AEMath::InvSqrtF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[1] ) ) );
					fSelf.quadFloat[2] = AEFLOAT32( AEMath::InvSqrtF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[2] ) ) );
					fSelf.quadFloat[3] = AEFLOAT32( AEMath::InvSqrtF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[3] ) ) );
				}
				break;
			default:         
				{
					fSelf.quadFloat[0] = AEMath::SqrtInverse( vcVector.m_qfVector.quadFloat[0] );
					fSelf.quadFloat[1] = AEMath::SqrtInverse( vcVector.m_qfVector.quadFloat[1] );
					fSelf.quadFloat[2] = AEMath::SqrtInverse( vcVector.m_qfVector.quadFloat[2] );
					fSelf.quadFloat[3] = AEMath::SqrtInverse( vcVector.m_qfVector.quadFloat[3] );
				}
				break;
			}
		}
	};
	
	template <AEMathAccuracyMode A>
	struct unrollf_setSqrtInverse<A, AE_SQRT_SET_ZERO>
	{
		AE_FORCEINLINE static void Apply( AEQuadFloat32 &fSelf, AEVector4fRefParam vcVector )
		{
			switch (A)
			{
			case AE_ACC_23_BIT: 
				{
					fSelf.quadFloat[0] = ( ( vcVector.m_qfVector.quadFloat[0] <= AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEFLOAT32( AEMath::InvSqrtF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[0] ) ) ) );
					fSelf.quadFloat[1] = ( ( vcVector.m_qfVector.quadFloat[1] <= AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEFLOAT32( AEMath::InvSqrtF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[1] ) ) ) );
					fSelf.quadFloat[2] = ( ( vcVector.m_qfVector.quadFloat[2] <= AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEFLOAT32( AEMath::InvSqrtF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[2] ) ) ) );
					fSelf.quadFloat[3] = ( ( vcVector.m_qfVector.quadFloat[3] <= AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEFLOAT32( AEMath::InvSqrtF32Approx23Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[3] ) ) ) );
				}
				break;
			case AE_ACC_12_BIT: 
				{
					fSelf.quadFloat[0] = ( ( vcVector.m_qfVector.quadFloat[0] <= AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEFLOAT32( AEMath::InvSqrtF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[0] ) ) ) );
					fSelf.quadFloat[1] = ( ( vcVector.m_qfVector.quadFloat[1] <= AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEFLOAT32( AEMath::InvSqrtF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[1] ) ) ) );
					fSelf.quadFloat[2] = ( ( vcVector.m_qfVector.quadFloat[2] <= AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEFLOAT32( AEMath::InvSqrtF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[2] ) ) ) );
					fSelf.quadFloat[3] = ( ( vcVector.m_qfVector.quadFloat[3] <= AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEFLOAT32( AEMath::InvSqrtF32Approx12Bit( AEFLOAT32( vcVector.m_qfVector.quadFloat[3] ) ) ) );
				}
				break;
			default:         
				{
					fSelf.quadFloat[0] = ( ( vcVector.m_qfVector.quadFloat[0] <= AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEMath::SqrtInverse( vcVector.m_qfVector.quadFloat[0] ) );
					fSelf.quadFloat[1] = ( ( vcVector.m_qfVector.quadFloat[1] <= AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEMath::SqrtInverse( vcVector.m_qfVector.quadFloat[1] ) );
					fSelf.quadFloat[2] = ( ( vcVector.m_qfVector.quadFloat[2] <= AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEMath::SqrtInverse( vcVector.m_qfVector.quadFloat[2] ) );
					fSelf.quadFloat[3] = ( ( vcVector.m_qfVector.quadFloat[3] <= AEFLOAT32( 0 ) ) ? AEFLOAT32( 0 ) : AEMath::SqrtInverse( vcVector.m_qfVector.quadFloat[3] ) );
				}
				break;
			}
		}
	};
} // End namespace 

template <AEMathAccuracyMode A, AEMathNegSqrtMode S>
AE_FORCEINLINE void AEVector4f::SetSqrtInverse( AEVector4fRefParam vcVector )
{
	AEVector4_AdvancedInterface::unrollf_setSqrtInverse<A,S>::Apply( m_qfVector, vcVector );
}

AE_FORCEINLINE void AEVector4f::SetSqrtInverse( AEVector4fRefParam vcVector )
{
	AEVector4_AdvancedInterface::unrollf_setSqrtInverse<AE_ACC_23_BIT,AE_SQRT_SET_ZERO>::Apply( m_qfVector, vcVector );
}

#endif // AE_VECTOR4F_SQRTFUNCS

#ifndef AE_VECTOR4F_LOADFUNCS

namespace AEVector4_AdvancedInterface
{
	template <int N, AEMathIoMode A>
	struct unrollf_load
	{
		AE_FORCEINLINE static void Apply( AEQuadFloat32 &qfSelf, const AEFLOAT32 *lpAddr )
		{
			AE_VECTOR4F_TEMPLATE_CONFIG_NOT_IMPLEMENTED;
		}
	};
	
	template <int N, AEMathIoMode A>
	struct unrollf_load_D
	{
		AE_FORCEINLINE static void Apply( AEQuadFloat32 &qfSelf, const AEDOUBLE64 *lpAddr )
		{
			AE_VECTOR4F_TEMPLATE_CONFIG_NOT_IMPLEMENTED;
		}
	};
	
	template <int N>
	struct unrollf_load<N, AE_IO_BYTE_ALIGNED>
	{
		AE_FORCEINLINE static void Apply( AEQuadFloat32 &qfSelf, const AEFLOAT32 *lpAddr )
		{
			#if defined(AE_PLATFORM_ANDROID)
				AEASSERT_MSG( ( ((AEUINT32)lpAddr) & (sizeof(AEFLOAT32)-1) ) == 0, "pointer must be aligned to native size of AEFLOAT32.");
			#endif
			
			qfSelf.quadFloat[0] = AEFLOAT32( lpAddr[0] );
			if( N >= 2 )
				qfSelf.quadFloat[1] = AEFLOAT32( lpAddr[1] );
			if( N >= 3 )
				qfSelf.quadFloat[2] = AEFLOAT32( lpAddr[2] );
			if( N >= 4 )
				qfSelf.quadFloat[3] = AEFLOAT32( lpAddr[3] );
			
			#if defined(AEDEBUG)
				#if defined(AE_REAL_IS_DOUBLE)
					for(int i=N; i<4; ++i) *((AEUINT64*)&( qfSelf.quadFloat[i] )) = 0xffffffffffffffffull;
				#else
					for(int i=N; i<4; ++i) *((AEUINT32*)&( qfSelf.quadFloat[i] )) = 0xffffffff;
				#endif
			#endif
		}
	};
	
	template <int N>
	struct unrollf_load_D<N, AE_IO_BYTE_ALIGNED>
	{
		AE_FORCEINLINE static void Apply( AEQuadFloat32 &qfSelf, const AEDOUBLE64 *lpAddr )
		{
			#if defined(AE_PLATFORM_ANDROID)
				AEASSERT_MSG( ( ((AEUINT32)lpAddr) & (sizeof(AEDOUBLE64)-1) ) == 0, "pointer must be aligned to native size of AEDOUBLE64.");
			#endif

			qfSelf.quadFloat[0] = AEDOUBLE64( lpAddr[0] );
			if( N >= 2 )
				qfSelf.quadFloat[1] = AEDOUBLE64( lpAddr[1] );
			if( N >= 3 )
				qfSelf.quadFloat[2] = AEDOUBLE64( lpAddr[2] );
			if( N >= 4 )
				qfSelf.quadFloat[3] = AEDOUBLE64( lpAddr[3] );
			
			#if defined(AEDEBUG)
				#if defined(AE_REAL_IS_DOUBLE)
					for(int i=N; i<4; ++i) *((AEUINT64*)&( qfSelf.quadFloat[i] )) = 0xffffffffffffffffull;
				#else
					for(int i=N; i<4; ++i) *((AEUINT32*)&( qfSelf.quadFloat[i] )) = 0xffffffff;
				#endif
			#endif
		}
	};
	
	template <int N>
	struct unrollf_load<N, AE_IO_NATIVE_ALIGNED>
	{
		AE_FORCEINLINE static void Apply( AEQuadFloat32 &qfSelf, const AEFLOAT32 *lpAddr )
		{
			AEASSERT_MSG( ( ((AEUINT32)lpAddr) & (sizeof(AEFLOAT32)-1) ) == 0, "pointer must be aligned to native size of AEFLOAT32.");
			unrollf_load<N, AE_IO_BYTE_ALIGNED>::Apply( qfSelf, lpAddr );
		}
	};
	
	template <int N>
	struct unrollf_load_D<N, AE_IO_NATIVE_ALIGNED>
	{
		AE_FORCEINLINE static void Apply( AEQuadFloat32 &qfSelf, const AEDOUBLE64 *lpAddr )
		{
			AEASSERT_MSG( ( ((AEUINT32)lpAddr) & (sizeof(AEDOUBLE64)-1) ) == 0, "pointer must be aligned to native size of AEDOUBLE64.");
			unrollf_load_D<N, AE_IO_BYTE_ALIGNED>::Apply( qfSelf, lpAddr );
		}
	};
	
	template <int N>
	struct unrollf_load<N, AE_IO_SIMD_ALIGNED>
	{
		AE_FORCEINLINE static void Apply( AEQuadFloat32 &qfSelf, const AEFLOAT32 *lpAddr )
		{
			AEASSERT_MSG( ( ((AEUINT32)lpAddr) & ((sizeof(AEFLOAT32)*(N!=3?N:4) )-1) ) == 0, "pointer must be aligned for SIMD.");
			unrollf_load<N, AE_IO_NATIVE_ALIGNED>::Apply( qfSelf, lpAddr );
		}
	};
	
	template <int N>
	struct unrollf_load_D<N, AE_IO_SIMD_ALIGNED>
	{
		AE_FORCEINLINE static void Apply( AEQuadFloat32 &qfSelf, const AEDOUBLE64 *lpAddr )
		{
			AEASSERT_MSG( ( ((AEUINT32)lpAddr) & ((sizeof(AEDOUBLE64)*(N!=3?N:4) )-1) ) == 0, "pointer must be aligned for SIMD.");
			unrollf_load_D<N, AE_IO_NATIVE_ALIGNED>::Apply( qfSelf, lpAddr );
		}
	};
	
	template <int N>
	struct unrollf_load<N, AE_IO_NOT_CACHED>
	{
		AE_FORCEINLINE static void Apply( AEQuadFloat32 &qfSelf, const AEFLOAT32 *lpAddr )
		{
			unrollf_load<N, AE_IO_SIMD_ALIGNED>::Apply( qfSelf, lpAddr );
		}
	};
	
	template <int N>
	struct unrollf_load_D<N, AE_IO_NOT_CACHED>
	{
		AE_FORCEINLINE static void Apply( AEQuadFloat32 &qfSelf, const AEDOUBLE64 *lpAddr )
		{
			unrollf_load_D<N, AE_IO_SIMD_ALIGNED>::Apply( qfSelf, lpAddr );
		}
	};
} // namespace 

template <AEINT32 N, AEMathIoMode A>
AE_FORCEINLINE void AEVector4f::Load( const AEFLOAT32 *lpAddr )
{
	AE_VECTOR4F_UNSUPPORTED_LENGTH_CHECK;
	AEVector4_AdvancedInterface::unrollf_load<N,A>::Apply( m_qfVector, lpAddr );
}

template <AEINT32 N, AEMathIoMode A>
AE_FORCEINLINE void AEVector4f::Load( const AEDOUBLE64 *lpAddr )
{
	AE_VECTOR4F_UNSUPPORTED_LENGTH_CHECK;
	AEVector4_AdvancedInterface::unrollf_load_D<N,A>::Apply( m_qfVector, lpAddr );
}

template <AEINT32 N>
AE_FORCEINLINE void AEVector4f::Load( const AEFLOAT32 *lpAddr )
{
	AE_VECTOR4F_UNSUPPORTED_LENGTH_CHECK;
	AEVector4_AdvancedInterface::unrollf_load<N,AE_IO_SIMD_ALIGNED>::Apply( m_qfVector, lpAddr );
}

template <AEINT32 N>
AE_FORCEINLINE void AEVector4f::Load( const AEDOUBLE64 *lpAddr )
{
	AE_VECTOR4F_UNSUPPORTED_LENGTH_CHECK;
	AEVector4_AdvancedInterface::unrollf_load_D<N,AE_IO_SIMD_ALIGNED>::Apply( m_qfVector, lpAddr );
}

#endif // AE_VECTOR4F_LOADFUNCS

#ifndef AE_VECTOR4F_STOREFUNCS

namespace AEVector4_AdvancedInterface
{
	template <int N, AEMathIoMode A>
	struct unrollf_store
	{
		AE_FORCEINLINE static void Apply( const AEQuadFloat32 &qfSelf, AEFLOAT32 *lpAddr )
		{
			AE_VECTOR4F_TEMPLATE_CONFIG_NOT_IMPLEMENTED;
		}
	};
	
	template <int N, AEMathIoMode A>
	struct unrollf_store_D
	{
		AE_FORCEINLINE static void Apply( const AEQuadFloat32 &qfSelf, AEDOUBLE64 *lpAddr )
		{
			AE_VECTOR4F_TEMPLATE_CONFIG_NOT_IMPLEMENTED;
		}
	};
	
	template <int N>
	struct unrollf_store<N, AE_IO_BYTE_ALIGNED>
	{
		AE_FORCEINLINE static void Apply( const AEQuadFloat32 &qfSelf, AEFLOAT32 *lpAddr )
		{
			#if defined(AE_PLATFORM_ANDROID)
				AEASSERT_MSG( ( ((AEUINT32)lpAddr) & (sizeof(AEFLOAT32)-1) ) == 0, "pointer must be aligned to native size of AEFLOAT32.");
			#endif
			
			lpAddr[0] = AEFLOAT32( qfSelf.quadFloat[0] );
			if( N >= 2 )
				lpAddr[1] = AEFLOAT32( qfSelf.quadFloat[1] );
			if( N >= 3 )
				lpAddr[2] = AEFLOAT32( qfSelf.quadFloat[2] );
			if( N >= 4 )
				lpAddr[3] = AEFLOAT32( qfSelf.quadFloat[3] );
		}
	};
	
	template <int N>
	struct unrollf_store_D<N, AE_IO_BYTE_ALIGNED>
	{
		AE_FORCEINLINE static void Apply( const AEQuadFloat32 &qfSelf, AEDOUBLE64 *lpAddr )
		{
			#if defined(AE_PLATFORM_ANDROID)
				AEASSERT_MSG( ( ((AEUINT32)lpAddr) & (sizeof(AEFLOAT32)-1) ) == 0, "pointer must be aligned to native size of AEFLOAT32.");
			#endif
			
			lpAddr[0] = AEDOUBLE64( qfSelf.quadFloat[0] );
			if( N >= 2 )
				lpAddr[1] = AEDOUBLE64( qfSelf.quadFloat[1] );
			if( N >= 3 )
				lpAddr[2] = AEDOUBLE64( qfSelf.quadFloat[2] );
			if( N >= 4 )
				lpAddr[3] = AEDOUBLE64( qfSelf.quadFloat[3] );
		}
	};
	
	template <int N>
	struct unrollf_store<N, AE_IO_NATIVE_ALIGNED>
	{ 
		AE_FORCEINLINE static void Apply( const AEQuadFloat32 &qfSelf, AEFLOAT32 *lpAddr )
		{
			AEASSERT_MSG( ( ( (AEUINT32)lpAddr) & (sizeof(AEFLOAT32)-1) ) == 0, "pointer must be aligned to native size of AEFLOAT32.");
			unrollf_store<N, AE_IO_BYTE_ALIGNED>::Apply( qfSelf, lpAddr );
		}
	};
	
	template <int N>
	struct unrollf_store_D<N, AE_IO_NATIVE_ALIGNED>
	{
		AE_FORCEINLINE static void Apply( const AEQuadFloat32 &qfSelf, AEDOUBLE64 *lpAddr )
		{
			AEASSERT_MSG( ( ((AEUINT32)lpAddr) & (sizeof(AEDOUBLE64)-1) ) == 0, "pointer must be aligned to native size of AEDOUBLE64.");
			unrollf_store_D<N, AE_IO_BYTE_ALIGNED>::Apply( qfSelf, lpAddr );
		}
	};
	
	template <int N>
	struct unrollf_store<N, AE_IO_SIMD_ALIGNED>
	{
		AE_FORCEINLINE static void Apply( const AEQuadFloat32 &qfSelf, AEFLOAT32 *lpAddr )
		{
			AEASSERT_MSG( ( ((AEUINT32)lpAddr) & ((sizeof(AEFLOAT32)*(N!=3?N:4) )-1) ) == 0, "pointer must be aligned for SIMD.");
			unrollf_store<N, AE_IO_NATIVE_ALIGNED>::Apply( qfSelf, lpAddr );
		}
	};
	
	template <int N>
	struct unrollf_store_D<N, AE_IO_SIMD_ALIGNED>
	{
		AE_FORCEINLINE static void Apply( const AEQuadFloat32 &qfSelf, AEDOUBLE64 *lpAddr )
		{
			AEASSERT_MSG( ( ((AEUINT32)lpAddr) & ((sizeof(AEDOUBLE64)*(N!=3?N:4) )-1) ) == 0, "pointer must be aligned for SIMD.");
			unrollf_store_D<N, AE_IO_NATIVE_ALIGNED>::Apply( qfSelf, lpAddr );
		}
	};
	
	template <int N>
	struct unrollf_store<N, AE_IO_NOT_CACHED>
	{
		AE_FORCEINLINE static void Apply( const AEQuadFloat32 &qfSelf, AEFLOAT32 *lpAddr )
		{
			unrollf_store<N, AE_IO_SIMD_ALIGNED>::Apply( qfSelf, lpAddr );
		}
	};
	
	template <int N>
	struct unrollf_store_D<N, AE_IO_NOT_CACHED>
	{
		AE_FORCEINLINE static void Apply( const AEQuadFloat32 &qfSelf, AEDOUBLE64 *lpAddr )
		{
			unrollf_store_D<N, AE_IO_SIMD_ALIGNED>::Apply( qfSelf, lpAddr );
		}
	};
} // End namespace

template <AEINT32 N, AEMathIoMode A, AEMathRoundingMode R>
AE_FORCEINLINE void AEVector4f::Store( AEFLOAT32 *lpAddr ) const
{
	AE_VECTOR4F_UNSUPPORTED_LENGTH_CHECK;
	AEVector4_AdvancedInterface::unrollf_store<N,A>::Apply( m_qfVector, lpAddr );
}

template <AEINT32 N, AEMathIoMode A, AEMathRoundingMode R>
AE_FORCEINLINE void AEVector4f::Store( AEDOUBLE64 *lpAddr ) const
{
	AE_VECTOR4F_UNSUPPORTED_LENGTH_CHECK;
	AEVector4_AdvancedInterface::unrollf_store_D<N,A>::Apply( m_qfVector, lpAddr );
}

template <AEINT32 N, AEMathIoMode A>
AE_FORCEINLINE void AEVector4f::Store( AEFLOAT32 *lpAddr ) const
{
	AE_VECTOR4F_UNSUPPORTED_LENGTH_CHECK;
	AEVector4_AdvancedInterface::unrollf_store<N,A>::Apply( m_qfVector, lpAddr );
}

template <AEINT32 N, AEMathIoMode A>
AE_FORCEINLINE void AEVector4f::Store( AEDOUBLE64 *lpAddr ) const
{
	AE_VECTOR4F_UNSUPPORTED_LENGTH_CHECK;
	AEVector4_AdvancedInterface::unrollf_store_D<N,A>::Apply( m_qfVector, lpAddr );
}

template <AEINT32 N>
AE_FORCEINLINE void AEVector4f::Store( AEFLOAT32* lpAddr ) const
{
	AE_VECTOR4F_UNSUPPORTED_LENGTH_CHECK;
	AEVector4_AdvancedInterface::unrollf_store<N,AE_IO_SIMD_ALIGNED>::Apply( m_qfVector, lpAddr );
}

template <AEINT32 N>
AE_FORCEINLINE void AEVector4f::Store( AEDOUBLE64 *lpAddr ) const
{
	AE_VECTOR4F_UNSUPPORTED_LENGTH_CHECK;
	AEVector4_AdvancedInterface::unrollf_store_D<N,AE_IO_SIMD_ALIGNED>::Apply( m_qfVector, lpAddr );
}

#endif // AE_VECTOR4F_STOREFUNCS

#ifndef AE_VECTOR4F_CMPFUNCS

AE_FORCEINLINE const AEVector4fComparison AEVector4f::CmpL( AEVector4fRefParam vcVector ) const
{
	AEVector4fComparison ret;
	ret.m_mMask =
		((m_qfVector.quadFloat[0]<vcVector.m_qfVector.quadFloat[0]) ? AEVector4ComparisonMask::MASK_X : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[1]<vcVector.m_qfVector.quadFloat[1]) ? AEVector4ComparisonMask::MASK_Y : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[2]<vcVector.m_qfVector.quadFloat[2]) ? AEVector4ComparisonMask::MASK_Z : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[3]<vcVector.m_qfVector.quadFloat[3]) ? AEVector4ComparisonMask::MASK_W : AEVector4ComparisonMask::MASK_NONE);
	return ret;
}

AE_FORCEINLINE const AEVector4fComparison AEVector4f::CmpLE( AEVector4fRefParam vcVector ) const
{
	AEVector4fComparison ret;
	ret.m_mMask =
		((m_qfVector.quadFloat[0]<=vcVector.m_qfVector.quadFloat[0]) ? AEVector4ComparisonMask::MASK_X : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[1]<=vcVector.m_qfVector.quadFloat[1]) ? AEVector4ComparisonMask::MASK_Y : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[2]<=vcVector.m_qfVector.quadFloat[2]) ? AEVector4ComparisonMask::MASK_Z : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[3]<=vcVector.m_qfVector.quadFloat[3]) ? AEVector4ComparisonMask::MASK_W : AEVector4ComparisonMask::MASK_NONE);
	return ret;
}

AE_FORCEINLINE const AEVector4fComparison AEVector4f::CmpG( AEVector4fRefParam vcVector ) const
{
	AEVector4fComparison ret;
	ret.m_mMask =
		((m_qfVector.quadFloat[0]>vcVector.m_qfVector.quadFloat[0]) ? AEVector4ComparisonMask::MASK_X : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[1]>vcVector.m_qfVector.quadFloat[1]) ? AEVector4ComparisonMask::MASK_Y : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[2]>vcVector.m_qfVector.quadFloat[2]) ? AEVector4ComparisonMask::MASK_Z : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[3]>vcVector.m_qfVector.quadFloat[3]) ? AEVector4ComparisonMask::MASK_W : AEVector4ComparisonMask::MASK_NONE);
	return ret;
}

AE_FORCEINLINE const AEVector4fComparison AEVector4f::CmpGE( AEVector4fRefParam vcVector ) const
{
	AEVector4fComparison ret;
	ret.m_mMask =
		((m_qfVector.quadFloat[0]>=vcVector.m_qfVector.quadFloat[0]) ? AEVector4ComparisonMask::MASK_X : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[1]>=vcVector.m_qfVector.quadFloat[1]) ? AEVector4ComparisonMask::MASK_Y : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[2]>=vcVector.m_qfVector.quadFloat[2]) ? AEVector4ComparisonMask::MASK_Z : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[3]>=vcVector.m_qfVector.quadFloat[3]) ? AEVector4ComparisonMask::MASK_W : AEVector4ComparisonMask::MASK_NONE);
	return ret;
}

AE_FORCEINLINE const AEVector4fComparison AEVector4f::CmpE( AEVector4fRefParam vcVector ) const
{
	AEVector4fComparison ret;
	ret.m_mMask =
		((m_qfVector.quadFloat[0]==vcVector.m_qfVector.quadFloat[0]) ? AEVector4ComparisonMask::MASK_X : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[1]==vcVector.m_qfVector.quadFloat[1]) ? AEVector4ComparisonMask::MASK_Y : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[2]==vcVector.m_qfVector.quadFloat[2]) ? AEVector4ComparisonMask::MASK_Z : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[3]==vcVector.m_qfVector.quadFloat[3]) ? AEVector4ComparisonMask::MASK_W : AEVector4ComparisonMask::MASK_NONE);
	return ret;
}

AE_FORCEINLINE const AEVector4fComparison AEVector4f::CmpNE( AEVector4fRefParam vcVector ) const
{
	AEVector4fComparison ret;
	ret.m_mMask =
		((m_qfVector.quadFloat[0]==vcVector.m_qfVector.quadFloat[0]) ? AEVector4ComparisonMask::MASK_NONE : AEVector4ComparisonMask::MASK_X) |
		((m_qfVector.quadFloat[1]==vcVector.m_qfVector.quadFloat[1]) ? AEVector4ComparisonMask::MASK_NONE : AEVector4ComparisonMask::MASK_Y) |
		((m_qfVector.quadFloat[2]==vcVector.m_qfVector.quadFloat[2]) ? AEVector4ComparisonMask::MASK_NONE : AEVector4ComparisonMask::MASK_Z) |
		((m_qfVector.quadFloat[3]==vcVector.m_qfVector.quadFloat[3]) ? AEVector4ComparisonMask::MASK_NONE : AEVector4ComparisonMask::MASK_W);
	return ret;
}

AE_FORCEINLINE const AEVector4fComparison AEVector4f::LessZero( void ) const
{
	AEVector4fComparison ret;
	ret.m_mMask =
		((m_qfVector.quadFloat[0]<AEFLOAT32(0)) ? AEVector4ComparisonMask::MASK_X : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[1]<AEFLOAT32(0)) ? AEVector4ComparisonMask::MASK_Y : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[2]<AEFLOAT32(0)) ? AEVector4ComparisonMask::MASK_Z : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[3]<AEFLOAT32(0)) ? AEVector4ComparisonMask::MASK_W : AEVector4ComparisonMask::MASK_NONE);
	return ret;
}

AE_FORCEINLINE const AEVector4fComparison AEVector4f::LessEqualZero( void ) const
{
	AEVector4fComparison ret;
	ret.m_mMask =
		((m_qfVector.quadFloat[0]<=AEFLOAT32(0)) ? AEVector4ComparisonMask::MASK_X : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[1]<=AEFLOAT32(0)) ? AEVector4ComparisonMask::MASK_Y : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[2]<=AEFLOAT32(0)) ? AEVector4ComparisonMask::MASK_Z : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[3]<=AEFLOAT32(0)) ? AEVector4ComparisonMask::MASK_W : AEVector4ComparisonMask::MASK_NONE);
	return ret;
}

AE_FORCEINLINE const AEVector4fComparison AEVector4f::GreaterZero( void ) const
{
	AEVector4fComparison ret;
	ret.m_mMask =
		((m_qfVector.quadFloat[0]>AEFLOAT32(0)) ? AEVector4ComparisonMask::MASK_X : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[1]>AEFLOAT32(0)) ? AEVector4ComparisonMask::MASK_Y : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[2]>AEFLOAT32(0)) ? AEVector4ComparisonMask::MASK_Z : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[3]>AEFLOAT32(0)) ? AEVector4ComparisonMask::MASK_W : AEVector4ComparisonMask::MASK_NONE);
	return ret;
}

AE_FORCEINLINE const AEVector4fComparison AEVector4f::GreaterEqualZero( void ) const
{
	AEVector4fComparison ret;
	ret.m_mMask =
		((m_qfVector.quadFloat[0]>=AEFLOAT32(0)) ? AEVector4ComparisonMask::MASK_X : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[1]>=AEFLOAT32(0)) ? AEVector4ComparisonMask::MASK_Y : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[2]>=AEFLOAT32(0)) ? AEVector4ComparisonMask::MASK_Z : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[3]>=AEFLOAT32(0)) ? AEVector4ComparisonMask::MASK_W : AEVector4ComparisonMask::MASK_NONE);
	return ret;
}

AE_FORCEINLINE const AEVector4fComparison AEVector4f::EqualZero( void ) const
{
	AEVector4fComparison ret;
	ret.m_mMask =
		((m_qfVector.quadFloat[0]==AEFLOAT32(0)) ? AEVector4ComparisonMask::MASK_X : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[1]==AEFLOAT32(0)) ? AEVector4ComparisonMask::MASK_Y : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[2]==AEFLOAT32(0)) ? AEVector4ComparisonMask::MASK_Z : AEVector4ComparisonMask::MASK_NONE) |
		((m_qfVector.quadFloat[3]==AEFLOAT32(0)) ? AEVector4ComparisonMask::MASK_W : AEVector4ComparisonMask::MASK_NONE);
	return ret;
}

AE_FORCEINLINE const AEVector4fComparison AEVector4f::NotEqualZero( void ) const
{
	AEVector4fComparison ret;
	ret.m_mMask =
		( ( m_qfVector.quadFloat[0]==AEFLOAT32(0) ) ? AEVector4ComparisonMask::MASK_NONE : AEVector4ComparisonMask::MASK_X ) |
		( ( m_qfVector.quadFloat[1]==AEFLOAT32(0) ) ? AEVector4ComparisonMask::MASK_NONE : AEVector4ComparisonMask::MASK_Y ) |
		( ( m_qfVector.quadFloat[2]==AEFLOAT32(0) ) ? AEVector4ComparisonMask::MASK_NONE : AEVector4ComparisonMask::MASK_Z ) |
		( ( m_qfVector.quadFloat[3]==AEFLOAT32(0) ) ? AEVector4ComparisonMask::MASK_NONE : AEVector4ComparisonMask::MASK_W );
	return ret;
}
#endif // AE_VECTOR4F_CMPFUNCS

#ifndef AE_VECTOR4F_SIGNFUNCS
AE_FORCEINLINE const AEVector4fComparison AEVector4f::SignBitSet( void ) const
{
	AEVector4fComparison mask;
	mask.m_mMask  = AEVector4fComparison::MASK_NONE;
	mask.m_mMask |= AEMath::SignBitSet( m_qfVector.quadFloat[0] ) ? AEVector4fComparison::MASK_X : AEVector4fComparison::MASK_NONE;
	mask.m_mMask |= AEMath::SignBitSet( m_qfVector.quadFloat[1] ) ? AEVector4fComparison::MASK_Y : AEVector4fComparison::MASK_NONE;
	mask.m_mMask |= AEMath::SignBitSet( m_qfVector.quadFloat[2] ) ? AEVector4fComparison::MASK_Z : AEVector4fComparison::MASK_NONE;
	mask.m_mMask |= AEMath::SignBitSet( m_qfVector.quadFloat[3] ) ? AEVector4fComparison::MASK_W : AEVector4fComparison::MASK_NONE;
	return mask;
}

AE_FORCEINLINE const AEVector4fComparison AEVector4f::SignBitClear( void ) const
{
	AEVector4fComparison mask;
	mask.m_mMask  = AEVector4fComparison::MASK_NONE;
	mask.m_mMask |= AEMath::SignBitSet( m_qfVector.quadFloat[0] ) ? AEVector4fComparison::MASK_NONE : AEVector4fComparison::MASK_X;
	mask.m_mMask |= AEMath::SignBitSet( m_qfVector.quadFloat[1] ) ? AEVector4fComparison::MASK_NONE : AEVector4fComparison::MASK_Y;
	mask.m_mMask |= AEMath::SignBitSet( m_qfVector.quadFloat[2] ) ? AEVector4fComparison::MASK_NONE : AEVector4fComparison::MASK_Z;
	mask.m_mMask |= AEMath::SignBitSet( m_qfVector.quadFloat[3] ) ? AEVector4fComparison::MASK_NONE : AEVector4fComparison::MASK_W;
	return mask;
}

AE_FORCEINLINE void AEVector4f::SetFlipSign( AEVector4fRefParam vcVector, AEVector4fConstRefCompParam sSign )
{
	m_qfVector.quadFloat[0] = sSign.AnyIsSet<AEVector4ComparisonMask::MASK_X>() ? -vcVector.m_qfVector.quadFloat[0] : vcVector.m_qfVector.quadFloat[0];
	m_qfVector.quadFloat[1] = sSign.AnyIsSet<AEVector4ComparisonMask::MASK_Y>() ? -vcVector.m_qfVector.quadFloat[1] : vcVector.m_qfVector.quadFloat[1];
	m_qfVector.quadFloat[2] = sSign.AnyIsSet<AEVector4ComparisonMask::MASK_Z>() ? -vcVector.m_qfVector.quadFloat[2] : vcVector.m_qfVector.quadFloat[2];
	m_qfVector.quadFloat[3] = sSign.AnyIsSet<AEVector4ComparisonMask::MASK_W>() ? -vcVector.m_qfVector.quadFloat[3] : vcVector.m_qfVector.quadFloat[3];
}

AE_FORCEINLINE void AEVector4f::SetFlipSign( AEVector4fRefParam vcVector, AEVector4fRefParam vSign )
{
	m_qfVector.quadFloat[0] = AEMath::SignBitSet( vSign.m_qfVector.quadFloat[0]) ? -vcVector.m_qfVector.quadFloat[0] : vcVector.m_qfVector.quadFloat[0];
	m_qfVector.quadFloat[1] = AEMath::SignBitSet( vSign.m_qfVector.quadFloat[1]) ? -vcVector.m_qfVector.quadFloat[1] : vcVector.m_qfVector.quadFloat[1];
	m_qfVector.quadFloat[2] = AEMath::SignBitSet( vSign.m_qfVector.quadFloat[2]) ? -vcVector.m_qfVector.quadFloat[2] : vcVector.m_qfVector.quadFloat[2];
	m_qfVector.quadFloat[3] = AEMath::SignBitSet( vSign.m_qfVector.quadFloat[3]) ? -vcVector.m_qfVector.quadFloat[3] : vcVector.m_qfVector.quadFloat[3];
}

#endif // AE_VECTOR4F_SIGNFUNCS

#ifndef AE_VECTOR4F_SELECTFUNCS
AE_FORCEINLINE void AEVector4f::SetSelect( AEVector4fConstRefCompParam vcCompareMask, AEVector4fRefParam vcTrueValue, AEVector4fRefParam vcFalseValue )
{
	m_qfVector.quadFloat[0] = vcCompareMask.AnyIsSet<AEVector4ComparisonMask::MASK_X>() ? vcTrueValue.m_qfVector.quadFloat[0] : vcFalseValue.m_qfVector.quadFloat[0];
	m_qfVector.quadFloat[1] = vcCompareMask.AnyIsSet<AEVector4ComparisonMask::MASK_Y>() ? vcTrueValue.m_qfVector.quadFloat[1] : vcFalseValue.m_qfVector.quadFloat[1];
	m_qfVector.quadFloat[2] = vcCompareMask.AnyIsSet<AEVector4ComparisonMask::MASK_Z>() ? vcTrueValue.m_qfVector.quadFloat[2] : vcFalseValue.m_qfVector.quadFloat[2];
	m_qfVector.quadFloat[3] = vcCompareMask.AnyIsSet<AEVector4ComparisonMask::MASK_W>() ? vcTrueValue.m_qfVector.quadFloat[3] : vcFalseValue.m_qfVector.quadFloat[3];
}

template<AEVector4ComparisonMask::Mask M>
AE_FORCEINLINE void AEVector4f::SetSelect( AEVector4fRefParam vcTrueValue, AEVector4fRefParam vcFalseValue )
{
	m_qfVector.quadFloat[0] = ( M & AEVector4ComparisonMask::MASK_X ) ? vcTrueValue.m_qfVector.quadFloat[0] : vcFalseValue.m_qfVector.quadFloat[0];
	m_qfVector.quadFloat[1] = ( M & AEVector4ComparisonMask::MASK_Y ) ? vcTrueValue.m_qfVector.quadFloat[1] : vcFalseValue.m_qfVector.quadFloat[1];
	m_qfVector.quadFloat[2] = ( M & AEVector4ComparisonMask::MASK_Z ) ? vcTrueValue.m_qfVector.quadFloat[2] : vcFalseValue.m_qfVector.quadFloat[2];
	m_qfVector.quadFloat[3] = ( M & AEVector4ComparisonMask::MASK_W ) ? vcTrueValue.m_qfVector.quadFloat[3] : vcFalseValue.m_qfVector.quadFloat[3];
}
#endif // AE_VECTOR4F_SELECTFUNCS

#ifndef AE_VECTOR4F_ROTATE_FUNCS

AE_FORCEINLINE void AEVector4f::SetRotatedDir( const AEMatrix3f &mtMatrix, AEVector4fRefParam vcVector )
{
	const AESimdFloat32 v0 = vcVector.GetComponent<0>();
	const AESimdFloat32 v1 = vcVector.GetComponent<1>();
	const AESimdFloat32 v2 = vcVector.GetComponent<2>();

	SetMul( mtMatrix.GetColumn<0>(), v0 );
	AddMul( mtMatrix.GetColumn<1>(), v1 );
	AddMul( mtMatrix.GetColumn<2>(), v2 );
}

AE_FORCEINLINE void AEVector4f::SetRotatedInverseDir( const AEMatrix3f &mtMatrix, AEVector4fRefParam vcVector )
{
	const AESimdFloat32 d0 = mtMatrix.GetColumn<0>().GetDot<3>( vcVector );
	const AESimdFloat32 d1 = mtMatrix.GetColumn<1>().GetDot<3>( vcVector );
	const AESimdFloat32 d2 = mtMatrix.GetColumn<2>().GetDot<3>( vcVector );

	Set(d0,d1,d2,d2);
}

#endif // AE_VECTOR4F_ROTATE_FUNCS

#endif // _AEVECTOR4FFPU_INL_
